【POJ1985】Cow Marathon

树的直径的模板题

我们存图以后,对这张图(树)进行一次dfs,定义sum1表示从当前节点向他的儿子走的最长路径是多少,sum2表示次长路径是多少。我们每次先用当前路径的长度+当前路径前往的节点的sum1更新当前节点的sum2,如果更新后sum2大于sum1,那么我们交换他们的数值,不难发现这样是正确的,计算完成后我们向当前节点的父亲返回他的sum1,这样之后答案ans就是max(sum1+sum2),这个算法将每一个点遍历一遍,因此,时间复杂度为O(n)。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 int n,m;
 8 struct edge {
 9     int next,to,dis;
10 }a[100010<<1];
11 int num,head[100010<<1];
12 int f[100010],ans;
13 void add(int from,int to,int dis) {
14     a[++num].next=head[from];
15     a[num].to=to;
16     a[num].dis=dis;
17     head[from]=num;
18 }
19 int dfs(int u,int fa) {
20     int sum1=0,sum2=0;
21     for(int i=head[u];i;i=a[i].next)
22         if(a[i].to!=fa) {
23             sum2=max(sum2,dfs(a[i].to,u)+a[i].dis);
24             if(sum2>sum1) swap(sum1,sum2);
25             ans=max(ans,sum1+sum2);
26         }
27     return sum1;
28 }
29 int main() {
30     scanf("%d%d",&n,&m);
31     for(int i=1;i<=m;i++) {
32         char c;
33         int x,y,z;
34         cin>>x>>y>>z>>c;
35         add(x,y,z);
36         add(y,x,z);
37     }
38     dfs(1,0);
39     printf("%d\n",ans);
40     return 0;
41 }
AC Code

 

posted @ 2019-06-01 21:02  AD_shl  阅读(266)  评论(0编辑  收藏  举报