hdu4714 Tree2cycle

原创 2013年09月09日 19:08:52

原题链接:

    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 1100000
using 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;
}



内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:hdu4714 Tree2cycle
举报原因:
原因补充:

(最多只允许输入30个字)