题意:给一棵树,删除一条边和增加一条边代价都是1,问把所有节点连成环,最少的代价。
思路:可以将树删成ans+1条链,答案就是ans+ans+1。如果一个节点的分支数大于1的话,就把该点与父节点的边删点,该节点形成的链数就是son-1。树的根节点注意,应为根节点可以有两个分支。
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> const int N=1000100; int head[N],num,ans; struct edge { int ed,next; }e[N*2]; void addedge(int x,int y) { e[num].ed=y;e[num].next=head[x];head[x]=num++; e[num].ed=x;e[num].next=head[y];head[y]=num++; } int dfs(int u,int fa) { int i,v,son=0; for(i=head[u];i!=-1;i=e[i].next) { v=e[i].ed; if(v==fa)continue; son+=dfs(v,u); } if(son>=2)//将该节点与父节点的边删去 { ans+=son-1;//删去后新加了son-1条链 if(u==1)ans--;//根节点可以有两个分支 return 0; } else return 1; } int main() { int i,x,y,n,t; scanf("%d",&t); while(t--) { memset(head,-1,sizeof(head)); num=0; scanf("%d",&n); for(i=1;i<n;i++) { scanf("%d%d",&x,&y); addedge(x,y); } ans=0; dfs(1,0); printf("%d ",ans*2+1); } return 0; }