http://www.javashuo.com/article/p-dvbugxbr-eb.htmlhtml
對於一顆有邊權的樹,,它的直徑表示樹中最遠的兩個節點之間的距離,,,node
能夠經過兩次深搜(廣搜)來求出直徑ios
從任意起點s開始,,求出到s的最遠的節點node,,而後再從node開始求出到node最遠的節點,,,搜索的過程當中更新節點的值和距離,,c++
剛剛作的一道題,,當時感受是兩倍的權值和減去一個最遠的路,,,可是當時不會求最遠的路的距離,,就放棄了,,,後來有人說就是這個思想,,,就看了一下樹的直徑怎麼求,,,固然這題是求出到節點1最遠的路,,不是直徑,,,code
紅書上的板子有點長,,並且建圖方式不怎麼用,,就無論了,,htm
// #include <bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstdlib> #include <string.h> //#include <vector> #include <queue> #define aaa cout<<233<<endl; #define endl '\n' #define pb push_back using namespace std; typedef long long ll; typedef unsigned long long ull; const int inf = 0x3f3f3f3f;//1061109567 const ll linf = 0x3f3f3f3f3f3f3f; const double eps = 1e-6; const double pi = 3.14159265358979; const int maxn = 1e5 + 5; const int maxm = 2e5 + 5; const int mod = 1e9 + 7; struct edge { int to, next, w; }edge[maxn]; int tot, head[maxn]; void init() { tot = 0; memset(head, -1, sizeof head); } void addedge(int u, int v, int w) { edge[tot].to = v; edge[tot].w = w; edge[tot].next = head[u]; head[u] = tot++; } int ans, node, sum; int dis[maxn]; bool vis[maxn]; void dfs(int u) { for(int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to; if(!vis[v]) { vis[v] = true; dis[v] = dis[u] + edge[i].w; if(dis[v] > ans) { ans = dis[v]; node = v; } dfs(v); } } } void bfs(int s, int n) { queue<int> q; while(!q.empty())q.pop(); q.push(s); vis[s] = true; while(!q.empty()) { int u = q.front(); q.pop(); for(int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to; if(!vis[v]) { vis[v] = true; dis[v] = dis[u] + edge[i].w; q.push(v); if(dis[v] > ans) { ans = dis[v]; node = v; } } } } } void solve(int n) { // memset(dis, 0, sizeof dis); // memset(vis, false, sizeof vis); // ans = 0; // node = 0; // vis[1] = true; // dfs(1); memset(dis, 0, sizeof dis); memset(vis, false, sizeof vis); ans = 0; node = 0; vis[1] = true; bfs(1, n); ans = sum * 2 - ans; cout << ans << endl; } int main() { // freopen("233.in" , "r" , stdin); // freopen("233.out" , "w" , stdout); ios_base::sync_with_stdio(0); cin.tie(0);cout.tie(0); int n; cin >> n; int u, v, w; init(); sum = 0; for(int i = 1; i <= n - 1; ++i) { cin >> u >> v >> w; addedge(u, v, w); addedge(v, u, w); sum += w; } solve(n); return 0; }
裸題,,求樹的最長路,,也就是直徑,,blog
// #include <bits/stdc++.h> #include <iostream> #include <cstdio> #include <cstdlib> #include <string.h> //#include <vector> #include <queue> #define aaa cout<<233<<endl; #define endl '\n' #define pb push_back using namespace std; typedef long long ll; typedef unsigned long long ull; const int inf = 0x3f3f3f3f;//1061109567 const ll linf = 0x3f3f3f3f3f3f3f; const double eps = 1e-6; const double pi = 3.14159265358979; const int maxn = 1e5 + 5; const int maxm = 2e5 + 5; const int mod = 1e9 + 7; struct edge { int to, next, w; }edge[maxn]; int tot, head[maxn]; void init() { tot = 0; memset(head, -1, sizeof head); } void addedge(int u, int v, int w) { edge[tot].to = v; edge[tot].w = w; edge[tot].next = head[u]; head[u] = tot++; } int dis[maxn]; bool vis[maxn]; int ans, node; void dfs(int u) { for(int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to; if(!vis[v]) { dis[v] = dis[u] + edge[i].w; vis[v] =true; if(dis[v] > ans) { ans = dis[v]; node = v; } dfs(v); } } } void solve() { memset(vis, false, sizeof vis); memset(dis, 0, sizeof dis); ans = 0; node = 0; vis[1] = true; dfs(1); memset(vis, false, sizeof vis); memset(dis, 0, sizeof dis); vis[node] = true; ans = 0; dfs(node); printf("%d", ans); } int main() { // freopen("233.in" , "r" , stdin); // freopen("233.out" , "w" , stdout); // ios_base::sync_with_stdio(0); // cin.tie(0);cout.tie(0); init(); int u, v, w; while(~scanf("%d%d%d", &u, &v, &w)) { addedge(u, v, w); addedge(v, u, w); } solve(); return 0; }
(end)ci