P3629 [APIO2010]巡逻
好题
#include <bits/stdc++.h>
using namespace std;
const int maxn = 200010;
int head[maxn],to[maxn],Next[maxn],edge[maxn];
int d[maxn];
int cnt,n,k;
void add(int x, int y, int w)
{
to[++cnt]=y;edge[cnt]=w;
Next[cnt]=head[x];
head[x]=cnt;
}
int mmax,mp;
void dfs(int p,int fa,int w)//1 0 0
{
if(w>mmax)
{
mp=p;
mmax=w;
}
for(int i=head[p];i!=0;i=Next[i])
{
if(fa!=to[i])
dfs(to[i],p,w+edge[i]);
}
}
void dp(int x,int fa)
{
for(int i=head[x];i!=0;i=Next[i])
{
if(to[i]==fa)continue;
dp(to[i],x);
mmax=max(mmax,d[x]+d[to[i]]+edge[i]);
d[x]=max(d[x],d[to[i]]+edge[i]);
}
}
int R1,R2;
int Dflag=0;
void dfs_D(int x,int fa,int dd)
{
if(Dflag==1)return;
if(x==dd)
{
Dflag=1;
return;
}
for(int i=head[x];i!=0;i=Next[i])
{
if(to[i]==fa)continue;
dfs_D(to[i],x,dd);
if(Dflag==1)
{
edge[i]=-1;
return;
}
}
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n>>k;
for(int i=1;i<n;i++)
{
int a,b;
cin>>a>>b;
add(a,b,1);
add(b,a,1);
}
if(k==1)
{
dp(1,0);
cout<<2*(n-1)-mmax+1<<endl;
}//30分,正确。
else if(k==2)
{
dfs(1,0,0);
R1=mp;
mmax=0;
dfs(R1,0,0);
R2=mp;
int mmax1=mmax;
mmax=0;
Dflag=0;
dfs_D(R2,0,R1);
Dflag=0;
dfs_D(R1,0,R2);
dp(1,0);
cout<<2*n-mmax1-mmax<<endl;
}//100分
}