这个题标签为什么会有网络流。。
首先树的直径求法就是两遍dfs
然后以其中一个为树的根,统计子树到节点的最长距离与次长距离:
符合条件的点一定是最长距离唯一的,且次长距离与到根的距离不相等
注:
1、同级语句的顺序
2、long long
码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 500000
int hou[N],tot,xia[N],a,b,c,fu[N],zhong[N],id[N],ans,n,m,i,j;
long long v[N],d[N],d2[N],maxx;
void jian(int a,int b,long long c)
{
++tot;hou[tot]=xia[a];xia[a]=tot;zhong[tot]=b;v[tot]=c;
}
void jia(int a,int b,long long c)
{
jian(a,b,c);jian(b,a,c);
}
void dfs(int o,int fa)
{
int i;
d[o]=0;
id[o]=o;
for(i=xia[o];i!=0;i=hou[i])
{
int nd=zhong[i];
if(nd==fa)continue;
dfs(nd,o);
if(d[nd]+v[i]>d[o])d[o]=d[nd]+v[i],id[o]=id[nd];
}
}
void dp(int o,int fa)
{
int i;
fu[o]=fa;
id[o]=0;
for(i=xia[o];i!=-1;i=hou[i])
{
int nd=zhong[i];
if(nd==fa)continue;
dp(nd,o);
if(d[nd]+v[i]==d[o])
{
id[o]=1;
}else
if(d[nd]+v[i]>d[o])
{
id[o]=0;
d2[o]=d[o];
d[o]=d[nd]+v[i];
}else
if(d[nd]+v[i]>d2[o])
d2[o]=d[nd];
}
}
int main()
{ memset(xia,-1,sizeof(xia));
scanf("%d",&n);
for(i=1;i<n;i++)
{
scanf("%d%d%d",&a,&b,&c);
jia(a,b,c);
}
dfs(1,0);
int st=id[1];
dfs(st,0);
int nd=id[st];
maxx=d[st];
printf("%lld\n",maxx);
memset(d,0,sizeof(d));
dp(st,0);
int o=nd,ans=0;
while(o)
{//cout<<o;
if(id[o]==1&&d2[o]==maxx-d[o])
{
ans=0;
break;
}
if(d2[o]==maxx-d[o])
{
break;
}
if(id[o]==0)
{
++ans;
}
if(id[o]==1)
{
ans=1;
}
o=fu[o];
}
if(o==st)ans--;
printf("%d",ans);
}