【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 }