【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 }
posted @ 2018-03-28 20:12  LesRoad  阅读(307)  评论(0编辑  收藏  举报