hdu4714 Tree2cycle

来源:互联网 发布:java poi 自动列宽 编辑:程序博客网 时间:2024/06/05 20:15

原题链接:

    hdu 4714 Tree2cycle

题目大意:给一棵树节点数最多为1000000 ,把这棵树通过删边 和加边使这棵树变成一个环,其中删边和加边的的代价都为 1,输出最小代价。

题目分析:由于最终要形成一个环其拥有的的边一定为n,故可以只讨论要删除多少条边, 由于要形成环,删边后每个节点最多只能有两个节点,

 如果 当前节点有多于2个子节点与其相连,其与父亲节点连接的边要删除。


喳喳代码:

#pragma comment(linker, "/STACK:167772160")//手动扩栈~~~~hdu 用c++交#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#define N 1100000using namespace std;vector<int> tree[N];int n;int num;int dfs(int pos,int p)//如果当前节点与父亲节点的连线要删去返回1否则返回0{    int len=tree[pos].size();    if(len==1&&tree[pos][0]==p)        return 1;    int k=0;//记录当前节点的所有子节点返回的没有删除的与子节点连边的个数    int t;    for(int i=0; i<len; i++)    {        t=tree[pos][i];        if(t==p)continue;        k+=dfs(t,pos);    }    if(k>=2)//如果k>=2表示应该删除与父节点相连的边    {        num+=k-2;        if(pos!=1)            num++;        return 0;    }    return 1;}int main(){    //freopen("in.txt","r",stdin);    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        for(int i=1; i<=n; i++)            tree[i].clear();        int a,b;        for(int i=0; i<n-1; i++)        {            scanf("%d%d",&a,&b);            tree[a].push_back(b);            tree[b].push_back(a);        }        num=0;//表示要删除的边数        dfs(1,-1);        int ans=2*num+1;        printf("%d\n",ans);    }    return 0;}


原创粉丝点击