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