NOIP2015提高組.運輸計劃

題目

521. 運輸計劃
在這里插入圖片描述

算法標簽: 樹上倍增, l c a lca lca, 前綴和, 樹上差分, 二分

思路

注意到答案是具有二分性質的, 對于某個時間 m i d mid mid假設是最優答案, 小于該時間是不可以的, 但是大于該時間是可行的, 因此可以二分答案

這樣就將問題轉化為, 對于給定的時間 m i d mid mid, 將樹中的一條邊權變為 0 0 0, 所有的運輸路線耗時是否 ≤ m i d \le mid mid
可以將所有運輸的路線分為兩類, 一種是運輸時間 ≤ m i d \le mid mid的, 這種路線不要需要刪除邊
但是還有一種路線是 > m i d > mid >mid, 對于這些路線需要找個這些路線的公共邊, 將這個公共邊的權值變為 0 0 0, 但是直接枚舉所有的邊和路線會超時, 因此需要進行優化

可以在所有路線上的邊 + 1 + 1 +1, 最終結果就是公共邊被加了 t t t次, t t t是大于 m i d mid mid的路線的數量, 這樣就找到了這個邊, 利用樹上差分, 實現對每個邊 + 1 +1 +1的操作

代碼

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>using namespace std;const int N = 300010, M = N << 1, K = 19;int n, m;
int head[N], ed[M], ne[M], w[M], idx;
int fa[N][K], depth[N], d[N];
struct Path {int u, v, p, d;
} path[N];
int s[N];void add(int u, int v, int val) {ed[idx] = v, ne[idx] = head[u], w[idx] = val, head[u] = idx++;
}void dfs(int u, int pre, int dep) {depth[u] = dep;for (int i = head[u]; ~i; i = ne[i]) {int v = ed[i];if (v == pre) continue;fa[v][0] = u;for (int k = 1; k < K; ++k) fa[v][k] = fa[fa[v][k - 1]][k - 1];d[v] = d[u] + w[i];dfs(v, u, dep + 1);}
}int lca(int u, int v) {if (depth[u] < depth[v]) swap(u, v);for (int k = K - 1; k >= 0; --k) {if (depth[fa[u][k]] >= depth[v]) {u = fa[u][k];}}if (u == v) return v;for (int k = K - 1; k >= 0; --k) {if (fa[u][k] != fa[v][k]) {u = fa[u][k];v = fa[v][k];}}return fa[u][0];
}void dfs_sum(int u, int pre) {for (int i = head[u]; ~i; i = ne[i]) {int v = ed[i];if (v == pre) continue;dfs_sum(v, u);s[u] += s[v];}
}bool check(int mid) {memset(s, 0, sizeof s);int c = 0, max_d = 0;for (int i = 0; i < m; ++i) {auto [u, v, p, val] = path[i];if (val > mid) {c++;max_d = max(max_d, val);s[u]++;s[v]++;s[p] -= 2;}}if (c == 0) return true;dfs_sum(1, -1);for (int u = 2; u <= n; ++u) {if (s[u] == c && max_d - (d[u] - d[fa[u][0]]) <= mid) {return true;}}return false;
}int main() {ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);memset(head, -1, sizeof head);cin >> n >> m;for (int i = 0; i < n - 1; ++i) {int u, v, w;cin >> u >> v >> w;add(u, v, w), add(v, u, w);}dfs(1, -1, 1);for (int i = 0; i < m; ++i) {int u, v;cin >> u >> v;int p = lca(u, v);int dis = d[u] + d[v] - 2 * d[p];path[i] = {u, v, p, dis};}int l = 0, r = 3e8;while (l < r) {int mid = l + r >> 1;if (check(mid)) r = mid;else l = mid + 1;}cout << l << "\n";return 0;
}

* v e c t o r vector vector存鄰接表會超時

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>using namespace std;typedef pair<int, int> PII;
const int N = 300010, M = N << 1, K = 19;int n, m;
vector<PII> head[N];
int fa[N][K], depth[N], d[N];
struct Path {int u, v, p, d;
};
vector<Path> path;
int s[M];void init() {path.resize(m + 1);
}void add(int u, int v, int w) {head[u].push_back({v, w});
}void dfs(int u, int pre, int dep) {depth[u] = dep;for (auto [v, w] : head[u]) {if (v == pre) continue;fa[v][0] = u;for (int k = 1; k < K; ++k) fa[v][k] = fa[fa[v][k - 1]][k - 1];d[v] = d[u] + w;dfs(v, u, dep + 1);}
}int lca(int u, int v) {if (depth[u] < depth[v]) swap(u, v);for (int k = K - 1; k >= 0; --k) {if (depth[fa[u][k]] >= depth[v]) {u = fa[u][k];}}if (u == v) return u;for (int k = K - 1; k >= 0; --k) {if (fa[u][k] != fa[v][k]) {u = fa[u][k];v = fa[v][k];}}return fa[u][0];
}void dfs_sum(int u, int fa) {for (auto [v, w] : head[u]) {if (v == fa) continue;dfs_sum(v, u);s[u] += s[v];}
}bool check(int mid) {memset(s, 0, sizeof s);int cnt = 0, max_d = 0;for (auto [u, v, p, dis] : path) {if (dis > mid) {cnt++;s[u]++;s[v]++;s[p] -= 2;max_d = max(max_d, dis);}}if (cnt == 0) return true;dfs_sum(1, -1);for (int u = 2; u <= n; ++u) {if (s[u] == cnt && max_d - (d[u] - d[fa[u][0]]) <= mid) return true;}return false;
}int main() {ios::sync_with_stdio(false);cin.tie(0), cout.tie(0);cin >> n >> m;init();for (int i = 0; i < n - 1; ++i) {int u, v, w;cin >> u >> v >> w;add(u, v, w), add(v, u, w);}dfs(1, -1, 1);for (int i = 0; i < m; ++i) {int u, v;cin >> u >> v;int p = lca(u, v);path[i] = {u, v, p, d[u] + d[v] - 2 * d[p]};}int l = 0, r = 3e8;while (l < r) {int mid = l + r >> 1;if (check(mid)) r = mid;else l = mid + 1;}cout << l << "\n";return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/76635.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/76635.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/76635.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL數據過濾、轉換與標準化

數據處理是數據庫操作的重要組成部分&#xff0c;尤其是在大量數據中查找、轉換和規范化目標信息的過程中。為了確保數據的有效性與一致性&#xff0c;MySQL提供了一系列數據過濾、轉換與標準化的功能。 本教程將深入探討數據過濾和轉換的基本方法及應用&#xff0c;內容涵蓋數…

英語學習4.11

gear 【名詞 / 動詞】 &#x1f449; 關鍵詞&#xff1a;齒輪、裝備、調節、使適應 名詞釋義&#xff1a; 齒輪&#xff1a; 一種機械裝置&#xff0c;用于傳遞動力或調節運動。 裝備、工具&#xff1a; 指用于某種活動的設備或工具。 汽車檔位&#xff1a; 汽車中用于改變…

SDC命令詳解:使用相對路徑訪問設計對象(current_instance命令)

相關閱讀 SDC命令詳解https://blog.csdn.net/weixin_45791458/category_12931432.html?spm1001.2014.3001.5482 在使用get_cells等命令訪問設計對象時&#xff0c;需要指定設計對象的名字&#xff0c;這個名字是一個相對路徑&#xff0c;本文就將對此進行討論。 相對路徑 使…

【問題記錄】記錄2個安裝Centos/Anolis系統卡死在安裝包階段的問題?(硬盤分區?換設備)

背景 問題就不詳細記錄了&#xff0c;本文記錄的是Centos/Anolis安裝中卡主的問題。這個問題遇到過幾十次了&#xff0c;嘗試過各種方法。最近一個偶然因素找到了原因。然后翻看歷史上出現這個問題的照片居然是相同的地方卡死。。。 有點意思。特此記錄&#xff0c;希望未來遇…

微信小程序中的openid的作用

微信小程序中的openid的作用 引言 在當今數字化時代&#xff0c;用戶體驗成為了產品成功與否的關鍵因素之一。微信小程序作為連接用戶與服務的重要橋梁&#xff0c;在提升用戶體驗方面發揮著重要作用。其中&#xff0c; openid&#xff08;開放身份標識符&#xff09;是微信小…

《Python星球日記》第25天:Pandas 數據分析

名人說&#xff1a;路漫漫其修遠兮&#xff0c;吾將上下而求索。—— 屈原《離騷》 創作者&#xff1a;Code_流蘇(CSDN)&#xff08;一個喜歡古詩詞和編程的Coder&#x1f60a;&#xff09; 訂閱專欄&#xff1a;《Python星球日記》 目錄 一、引言二、數據分組與聚合1. 分組操…

分布式系統-腦裂,redis的解決方案

感謝你的反饋&#xff01;很高興能幫到你。關于你提到的“腦裂”&#xff08;split-brain&#xff09;&#xff0c;這是一個分布式系統中的常見術語&#xff0c;尤其在像 Redis Cluster 這樣的高可用集群中會涉及。既然你問到了&#xff0c;我會從頭解釋“腦裂”的含義、Redis …

重構藝術 | 如何優雅地“提煉函數“

在工作中總數遇到非常多的長代碼&#xff0c;俗稱“屎山”&#xff0c;這類代碼讀起來特別費勁。自己想重構一遍&#xff0c;但是總感覺缺乏經驗指導&#xff0c;因此&#xff0c;多讀書&#xff0c;讀好書可能是最優解之一。讀《重構改善即有代碼的設計》有感&#xff0c;便寫…

每天學一個 Linux 命令(13):touch

Linux 文件管理命令:touch touch 是 Linux 中一個簡單但高頻使用的命令,主要用于創建空文件或修改文件的時間戳(訪問時間、修改時間)。它是文件管理和腳本操作的實用工具。 1. 命令作用 創建空文件:快速生成一個或多個空白文件。更新時間戳:修改文件的訪問時間(Access …

STM32HAL庫學習筆記

目錄 定時器 一些小細節 輸入捕獲計算信號頻率 輸入捕獲計算占空比與頻率 使用定時器不改變占空比的同時改變頻率的方法 串口 重定向原理 重定向代碼 怎么從串口接收到的字符串數據中解析出float型的數據 strchr sscanf memset 第一種實現方法 RTC實時時鐘 LCD顯…

Docker 鏡像、容器與數據卷的高效管理:最佳實踐與自動化腳本20250411

Docker 鏡像、容器與數據卷的高效管理&#xff1a;最佳實踐與自動化腳本 引言 在現代軟件開發中&#xff0c;容器化技術正變得越來越重要。Docker 作為容器化的代表工具&#xff0c;在各大企業中得到了廣泛的應用。然而&#xff0c;隨著容器化應用的增多&#xff0c;如何高效…

Selenium之Actions事件

鼠標、鍵盤組合鍵 在使用selenium的時候&#xff0c;有的時候我們需要鼠標單擊、雙擊、拖動&#xff1b;或者是按下鍵盤的某個鍵&#xff0c;松開某個按鍵&#xff0c;以及組合鍵的使用&#xff1b;今天我們就來看一看&#xff0c;怎么樣實現上面的操作 先把準備工作做好&…

如何在 CentOS 7 系統上以容器方式部署 GitLab,使用 ZeroNews 通過互聯網訪問 GitLab 私有倉庫,進行代碼版本發布與更新

第 1 步&#xff1a; 部署 GitLab 容器? 在開始部署 GitLab 容器之前&#xff0c;您需要創建本地目錄來存儲 GitLab 數據、配置和日志&#xff1a; #創建本地目錄 mkdir -p /opt/docker/gitlab/data mkdir -p /opt/docker/gitlab/config mkdir -p /opt/docker/gitlab/log#gi…

.py文件和.ipynb文件的區別:完整教程

一、概述 Python開發者常用的兩種文件格式.py和.ipynb各有特點&#xff0c;本教程將通過對比分析、代碼示例和場景說明&#xff0c;幫助開發者全面理解二者的區別與聯系。 二、核心區別對比 1. 文件格式本質 特性.ipynb文件.py文件文件類型JSON結構化文檔純文本文件存儲內容…

Go 字符串四種拼接方式的性能對比

簡介 使用完整的基準測試代碼文件&#xff0c;可以直接運行來比較四種字符串拼接方法的性能。 for 索引 的方式 for range 的方式 strings.Join 的方式 strings.Builder 的方式 寫一個基準測試文件 echo_bench_test.go package mainimport ("os""stri…

從代碼學習深度學習 - Bahdanau注意力 PyTorch版

文章目錄 1. 前言為什么選擇Bahdanau注意力本文目標與預備知識2. Bahdanau注意力機制概述注意力機制簡述加性注意力與乘性注意力對比Bahdanau注意力的數學原理與流程圖數學原理流程圖可視化與直觀理解3. 數據準備與預處理數據集簡介數據加載與預處理1. 讀取數據集2. 預處理文本…

19【動手學深度學習】卷積層

1. 從全連接到卷積 2. 圖像卷積 3. 圖形卷積代碼 互相關操作 import torch from torch import nn from d2l import torch as d2ldef corr2d(X, K):"""計算2維互相關運算"""h, w K.shapeY torch.zeros((X.shape[0]-h1, X.shape[1]-w 1))for …

Linux xorg-server 解析(一)- 編譯安裝Debug版本的xorg-server

一:下載代碼 1. 配置源,以Ubuntu24.04 為例( /etc/apt/sources.list.d/ubuntu.sources): 2. apt source xserver-xorg-core 二:編譯代碼 1. sudo apt build-dep ./ 2. DEB_BUILD_OPTIONS="nostrip" DEB_CFLAGS_SET="-g -O0" dpkg-buildpac…

大模型SFT用chat版還是base版 SFT后災難性遺忘怎么辦

大模型SFT用chat版還是base版 進行 SFT 時&#xff0c;基座模型選用 Chat 還是 Base 模型&#xff1f; 選 Base 還是 Chat 模型&#xff0c;首先先熟悉 Base 和 Chat 是兩種不同的大模型&#xff0c;它們在訓練數據、應用場景和模型特性上有所區別。 在訓練數據方面&#xf…

【圖像生成之21】融合了Transformer與Diffusion,Meta新作Transfusion實現圖像與語言大一統

論文&#xff1a;Transfusion: Predict the Next Token and Diffuse Images with One Multi-Modal Model 地址&#xff1a;https://arxiv.org/abs/2408.11039 類型&#xff1a;理解與生成 Transfusion模型?是一種將Transformer和Diffusion模型融合的多模態模型&#xff0c;旨…