小Q最近学习了一些图论知识。根据课本,有如下定义。树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度。如果一棵树有N个节点,可以证明其有且仅有N-1 条边。 路径:一棵树上,任意两个节点之间最多有一条简单路径。我们用 dis(a,b)
表示点a和点b的路径上各边长度之和。称dis(a,b)为a、b两个节点间的距离。
直径:一棵树上,最长的路径为树的直径。树的直径可能不是唯一的。
现在小Q想知道,对于给定的一棵树,其直径的长度是多少,以及有多少条边满足所有的直径都经过该边。
标签:mst 端点 php play bdc size page 学习 rip
小Q最近学习了一些图论知识。根据课本,有如下定义。树:无回路且连通的无向图,每条边都有正整数的权值来表示其长度。如果一棵树有N个节点,可以证明其有且仅有N-1 条边。 路径:一棵树上,任意两个节点之间最多有一条简单路径。我们用 dis(a,b)
表示点a和点b的路径上各边长度之和。称dis(a,b)为a、b两个节点间的距离。
直径:一棵树上,最长的路径为树的直径。树的直径可能不是唯一的。
现在小Q想知道,对于给定的一棵树,其直径的长度是多少,以及有多少条边满足所有的直径都经过该边。
第一行包含一个整数N,表示节点数。
接下来N-1行,每行三个整数a, b, c ,表示点 a和点b之间有一条长度为c
的无向边。
共两行。第一行一个整数,表示直径的长度。第二行一个整数,表示被所有
直径经过的边的数量。
对于100%的测试数据:2≤N≤200000,所有点的编号都在1..N的范围内,
边的权值≤10^9。
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <cmath> 7 #include <queue> 8 #include <map> 9 #include <set> 10 #include <vector> 11 #define N 200005 12 using namespace std; 13 int n,zz,a[N]; 14 struct ro{ 15 int to,next; 16 long long l; 17 }road[N*2]; 18 void build(int x,int y,int z) 19 { 20 zz++; 21 road[zz].next=a[x]; 22 road[zz].l=z; 23 road[zz].to=y; 24 a[x]=zz; 25 } 26 long long dis[N]; 27 int deep[N],fa[N]; 28 bool bj[N]; 29 void dfs1(int x) 30 { 31 for(int i=a[x];i;i=road[i].next) 32 { 33 int y=road[i].to; 34 if(y==fa[x])continue; 35 fa[y]=x; 36 deep[y]=deep[x]+1; 37 dis[y]=dis[x]+road[i].l; 38 dfs1(y); 39 } 40 } 41 int ans; 42 long long ma[N]; 43 void dfs2(int x) 44 { 45 long long mx=-1; 46 int js=0,js2=0; 47 for(int i=a[x];i>0;i=road[i].next) 48 { 49 int y=road[i].to; 50 if(y==fa[x])continue; 51 dfs2(y); 52 if(ma[y]>=mx) 53 { 54 if(ma[y]>mx)mx=ma[y],js=1; 55 else js++; 56 } 57 if(ma[y]-dis[x]==dis[x])js2++; 58 } 59 if(bj[x]) 60 { 61 if(js2) 62 { 63 ans-=deep[x]-1; 64 printf("%d\n",max(ans,0)); 65 exit(0); 66 } 67 else if(js>1) 68 { 69 ans=deep[x]-1; 70 } 71 } 72 mx=max(mx,dis[x]); 73 ma[x]=mx; 74 } 75 int main() 76 { 77 scanf("%d",&n); 78 for(int i=1;i<n;i++) 79 { 80 int x,y,z; 81 scanf("%d%d%d",&x,&y,&z); 82 build(x,y,z); 83 build(y,x,z); 84 } 85 dfs1(1); 86 memset(fa,0,sizeof(fa)); 87 int st1=0,st2=0; 88 for(int i=1;i<=n;i++)if(dis[i]>dis[st1]) st1=i; 89 memset(deep,0,sizeof(deep)); 90 deep[st1]=1; 91 memset(dis,0,sizeof(dis)); 92 dfs1(st1); 93 for(int i=1;i<=n;i++) if(dis[i]>dis[st2]) st2=i; 94 printf("%lld\n",dis[st2]); 95 ans=deep[st2]-1; 96 int now=st2; 97 while(now!=st1) 98 { 99 bj[now]=1; 100 now=fa[now]; 101 } 102 dfs2(st1); 103 printf("%d\n",ans); 104 return 0; 105 }
标签:mst 端点 php play bdc size page 学习 rip
原文地址:http://www.cnblogs.com/liutianrui/p/7780469.html