【lightoj-1094】树的直径(DFS)
链接:http://www.lightoj.com/volume_showproblem.php?problem=1094
题意:
一共n各节点编号0-n-1, 输入n-1条无向边代表u-v距离为w,求最远的两个点的距离(即树的直径)。
思路:
如果用最短路径来求,n<=30000是会超时的,正确做法是先随便从一个点开始深搜,搜到最远的节点一定是直径其中一个节点,然后从这个点再来次深搜。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 30004; 4 vector<pair<int, int> >V[N]; 5 bool vis[N]; 6 int Index, ans; 7 void dfs(int s, int sum) 8 { 9 vis[s] = 1; 10 if(ans < sum) 11 { 12 ans = sum; 13 Index = s; 14 } 15 for(unsigned int i = 0; i < V[s].size(); i++) 16 { 17 int v = V[s][i].first, w = V[s][i].second; 18 if(vis[v]) continue; 19 dfs(v, sum+w); 20 } 21 } 22 int main() 23 { 24 int n, t, cas = 0; 25 cin>>t; 26 while(t--) 27 { 28 scanf("%d", &n); 29 int a, b, c; 30 for(int i = 0; i <= n; i++) V[i].clear(); 31 for(int i = 0; i < n-1; i++) 32 { 33 scanf("%d%d%d", &a, &b, &c); 34 V[a].push_back(make_pair(b, c)); 35 V[b].push_back(make_pair(a, c)); 36 } 37 ans = 0; 38 memset(vis, 0, sizeof vis); 39 dfs(0, 0); 40 ans = 0; 41 memset(vis, 0, sizeof vis); 42 dfs(Index, 0); 43 printf("Case %d: %d\n", ++cas, ans); 44 } 45 return 0; 46 }