传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1912
题解:嗯,这是一道很好的题。
转自:http://www.cnblogs.com/iwtwiioi/p/4126284.html
对于 )
对于 1
可以证明不能减得更多啦。
z对于 1
可以证明不能减得更多啦。
我在这里就不贴出证明了,以免给读者养成不自己证明的惰性(其实是我这两天惰性有点大2333)
代码:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<cmath> 6 #define maxn 100005 7 #define maxm 200005 8 int n,k,c; 9 int ans,sum,mx,tot; 10 int s1[maxm],s2[maxm]; 11 int now[maxn],pre[maxm],v[maxm],val[maxm]; 12 int read() 13 { 14 int x=0; char ch; bool bo=0; 15 while (ch=getchar(),ch<'0'||ch>'9') if (ch=='-') bo=1; 16 while (x=x*10+ch-'0',ch=getchar(),ch>='0'&&ch<='9'); 17 if (bo) return -x; return x; 18 } 19 void ins(int a,int b,int c) 20 { 21 ++tot; pre[tot]=now[a]; now[a]=tot; v[tot]=b; val[tot]=c; 22 } 23 int dfs(int x,int fa) 24 { 25 int mx1=0,mx2=0; 26 for (int p=now[x]; p; p=pre[p]) 27 { 28 int son=v[p]; 29 if (son==fa) continue; 30 int vv=val[p]+dfs(son,x); 31 if (vv>mx1) mx2=mx1,mx1=vv,s2[x]=s1[x],s1[x]=p; 32 else if (vv>mx2) mx2=vv,s2[x]=p; 33 } 34 if (mx1+mx2>sum) sum=mx1+mx2,mx=x; 35 return mx1; 36 } 37 int main() 38 { 39 n=read(); k=read(); int c=1; 40 for (int i=1; i<n; i++) 41 { 42 int u=read(),v=read(),val=1; 43 ins(u,v,val); ins(v,u,val); 44 ans+=2*val; 45 } 46 dfs(1,0); 47 ans-=sum-1; 48 if (k==2) 49 { 50 for (int p=s1[mx]; p; p=s1[v[p]]) val[p]=-1*val[p]; 51 for (int p=s2[mx]; p; p=s1[v[p]]) val[p]=-1*val[p]; 52 sum=0; 53 dfs(1,0); ans-=sum-1; 54 } 55 printf("%d\n",ans); 56 }