hdu 4714由树变成环

来源:互联网 发布:9.3阅兵知乎 编辑:程序博客网 时间:2024/06/03 04:04
用到了手动扩栈要求用最少的操作把一颗树转化成一个环。其实就是把树分成最少的链,然后连接起来即可,仔细观察树的话会发现,一般一个点的度如果大于1的话,该点必然要断开一些连接,因为最终每个点的度都是2, 然后就是看点上断开那些连接了,其实,如果一个节点的除去父亲节点如果度大于1的话,断开与父亲节点的那条边必然是一种正解。。。于是问题就解决了,只需一遍dfs即可。在杭电交注意加上挂。。。不然会爆栈。。。#pragma comment(linker,"/STACK:102400000,102400000")   #include<stdio.h>#include<vector>#define N 1000100 using namespace std;vector<int>g[N];int ans;int dfs(int u,int fa){int i,num=0;for(i=0;i<g[u].size();i++){  int v=g[u][i];if(v==fa)continue;num+=dfs(v,u);}if(fa==-1&&num>1)//如果是根结点,保留两个分支ans+=num-2;else if(num>1)//如果不是根结点,保留两个分支,并且与父节点断开{ans+=num-1;return 0;}return 1;}int main(){int t,i,n,u,v;scanf("%d",&t);while(t--){scanf("%d",&n);for(i=0;i<=n;i++)g[i].clear();for(i=1;i<n;i++){scanf("%d%d",&u,&v);g[u].push_back(v);g[v].push_back(u);}ans=0;dfs(1,-1);printf("%d\n",ans+ans+1);//拆成n部分需要删除n-1条边,即n-1花费,连接n部分需要 n 花费,ans=n-1;}return 0;}

0 0