201503-4 网络延时 (本质是求树的最长路径)
生活随笔
收集整理的這篇文章主要介紹了
201503-4 网络延时 (本质是求树的最长路径)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
樹的最長路徑
- 題目:
- 思路:
- 求解方法:
- 動態規劃三部曲
- 1)狀態定義
- 2)狀態轉移方程
- (1)ACWing上的問題
- (2) POJ上的問題
- (3) CCF-CSP上的問題
參考博文:
<1>poj總結鏈接
<2> acwing 代碼鏈接
<3> 數學證明
相關題目鏈接
ACWing
POJ:
CCF-CSP:
題目:
對于一顆n個結點的無根樹,找到一條最長路徑。(找到兩個距離最遠的點)
思路:
(樹的重心問題)
先將無根樹轉換成有根樹,即隨意找一點i作為根節點,經過i的最長路就連接著兩顆不同子樹u和v的最深葉子節點的路徑。
求解方法:
任意找一點i為根節點,找到距離該結點最遠距離的點u。
再從u出發,尋找離u最遠的節點v。u到v的距離即為樹的最長路徑。
動態規劃三部曲
1)狀態定義
dp[i] 表示以i為根節點的子樹到葉節點的最大距離
2)狀態轉移方程
邊權為1時:
dp[i] = max{dp[j] + 1}
邊權不為1時:
dp[i] = max{dp[j] + w(i)}
(1)ACWing上的問題
類型:有邊權
#include <iostream> #include <cstring> #include <vector> using namespace std;const int N = 10010; int n; int ans; struct Node {int v, dis;Node(int _v, int _dis) {v = _v;dis = _dis;} }; vector<Node> Adj[N]; int dfs(int u, int father) {//根據貪心理論,以u為根的最長路徑必然由經過不同的子樹的最長和次長int d1 = 0, d2 = 0;for (int i = 0; i < Adj[u].size(); i++) {int v = Adj[u][i].v;int dis = Adj[u][i].dis;if (v == father)continue;int d = dfs(v, u) + dis; //u->v之前的距離//dist = max(dist, d);if (d >= d1) {d2 = d1;d1 = d;} else if (d > d2) {d2 = d;}}ans = max(ans, d1 + d2);//cout << d1 << endl;return d1; }int main() {cin >> n;int a, b, c;for (int i = 0; i < n - 1; i++) {cin >> a >> b >> c;Adj[a].push_back(Node(b, c));Adj[b].push_back(Node(a, c));}dfs(1, -1);cout << ans << endl;return 0; }(2) POJ上的問題
類型:有邊權
#include <iostream> #include <cstdlib> #include <cstring> #include <vector> using namespace std; const int N = 10010; int n, m;struct Node {int v, dis;Node(int _v, int _dis) {v = _v;dis = _dis;} }; vector<Node> Adj[N]; int dis[N]; int vis[N];void dfs(int u, int t) {dis[u] = t;for (int i = 0; i < Adj[u].size(); i++) {int v = Adj[u][i].v;if (vis[v] == false) {vis[v] = true;dfs(v, t + Adj[u][i].dis);}} }int main() {int u, v, w;int maxn = 0;while (cin >> u >> v >> w) {Adj[u].push_back(Node(v, w));Adj[v].push_back(Node(u, w));if (u > v) {maxn = max(maxn, u);} else {maxn = max(v, maxn);}}//cout << maxn << endl;memset(dis, 0, sizeof dis);fill(vis, vis + N, false);dfs(1, 0);int start = 0;int maxdis = 0;for (int i = 0; i <= maxn; i++) {if (dis[i] > maxdis) {start = i;maxdis = dis[i];}}memset(dis, 0, sizeof dis);fill(vis, vis + N, false);dfs(start, 0);maxdis = 0;for (int i = 0; i <= maxn; i++) {if (dis[i] > maxdis) {start = i;maxdis = dis[i];}}cout << maxdis << endl;return 0; }(3) CCF-CSP上的問題
類型:無邊權
#include <iostream> #include <vector> #include <cstring> #include <algorithm> using namespace std; const int N = 20010; int dis[N]; // 用于存儲最遠距離 bool vis[N]; int n, m; vector<int> Adj[N];void dfs(int start, int t) {dis[start] = t;for (int i = 0; i < Adj[start].size(); i++) {if (vis[Adj[start][i]] == false) {vis[Adj[start][i]] = true;dfs(Adj[start][i], t + 1);}} }int main() {cin >> n >> m;int a;for (int i = 2; i <= n; i++) {cin >> a;Adj[i].push_back(a);Adj[a].push_back(i);}for (int i = n + 1; i <= n + m; i++) {cin >> a;Adj[a].push_back(i);Adj[i].push_back(a);}memset(dis, 0, sizeof dis);fill(vis, vis + N, false);int start = 0;int maxdis = 0;//尋找最遠點udfs(1, 0);for (int i = 1; i <= n + m; i++) {if (dis[i] > maxdis) {start = i;maxdis = dis[i];}}maxdis = 0;memset(dis, 0, sizeof dis);fill(vis, vis + N, false);dfs(start, 0);for (int i = 1; i <= n + m; i++) {if (dis[i] > maxdis) {maxdis = dis[i];}}cout << maxdis << endl;return 0; }總結
以上是生活随笔為你收集整理的201503-4 网络延时 (本质是求树的最长路径)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机视觉基础:图像处理(上)
- 下一篇: SUMO学习