写一道题顶写三道题系列,
为了写这道题专门去学习了树的直径的两种求法,可以说是血赚了
https://www.luogu.com.cn/blog/lscsznmhw/solution-p3629
由于没学过类似题目,还是看了题解。。。
#include<bits/stdc++.h>
#define for1(i,a,b) for(ll i = a;i<=b;i++)
#define ll long long
#define mp(a,b) make_pair(a,b)
using namespace std;
struct node{
int nex;
int to;
int w;
} a[500010];
int hd[100010],cnt;
int n,k;
int mx,ji,d1,d2,st,ed,fr[100010],dis[100010];
bool kg;
map<int,bool>ma;
void ru(int x,int y)
{
a[++cnt].to=y;
a[cnt].nex=hd[x];
a[cnt].w=1;
hd[x]=cnt;
}
void dfs(int x,int fa,int we)
{
if(we>=mx)
{
mx=we;
ji=x;
}
for(int i=hd[x];i;i=a[i].nex)
if(a[i].to!=fa)
dfs(a[i].to,x,we+a[i].w);
}
void dfs2(int now,int fa,int t)
{
if(kg) return;
for(int i=hd[now]; i; i=a[i].nex)
{
if(kg) return;
if(a[i].to==fa) continue;
if(a[i].to==t)
{
fr[now]=a[i].to;
kg=1;
return;
}
fr[now]=a[i].to;
dfs2(a[i].to,now,t);
if(kg) return;
}
}
void dfs3(int now,int fa)
{
for(int i=hd[now]; i; i=a[i].nex)
{
if(a[i].to==fa) continue;
dfs3(a[i].to,now);
d2=max(d2,dis[now]+dis[a[i].to]+a[i].w);
dis[now]=max(dis[now],dis[a[i].to]+a[i].w);
}
}
int main()
{
int x,y;
cin>>n>>k;
for1(i,1,n-1)
{
cin>>x>>y;
ru(x,y);
ru(y,x);
}
dfs(1,0,0);
st=ji,mx=0;
dfs(st,0,0);
d1=mx,ed=ji;
if(k==1)
{
printf("%d",(2*(n-1)-d1+1));
return 0;
}
dfs2(st,0,ed);
ma[ed]=1,ma[st]=1;
for(int i=st;i!=ed;i=fr[i]) ma[i]=1;
for1(i,1,n)
if(ma.count(i)==1)
for(int j=hd[i];j;j=a[j].nex)
if(ma.count(a[j].to)==1)
a[j].w=-1;
dfs3(1,0);
printf("%d",2*n-d1-d2);
return 0;
}
标签:10,return,P3629,int,APIO2010,st,fa,now,hd
From: https://www.cnblogs.com/yyx525jia/p/16754328.html