hdu 4717 Tree2cycle(树形DP)

Tree2cycle

Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)
Total Submission(s): 2161    Accepted Submission(s): 508


Problem Description
A tree with N nodes and N-1 edges is given. To connect or disconnect one edge, we need 1 unit of cost respectively. The nodes are labeled from 1 to N. Your job is to transform the tree to a cycle(without superfluous edges) using minimal cost.

A cycle of n nodes is defined as follows: (1)a graph with n nodes and n edges (2)the degree of every node is 2 (3) each node can reach every other node with these N edges.
 

 

Input
The first line contains the number of test cases T( T<=10 ). Following lines are the scenarios of each test case.
In the first line of each test case, there is a single integer N( 3<=N<=1000000 ) - the number of nodes in the tree. The following N-1 lines describe the N-1 edges of the tree. Each line has a pair of integer U, V ( 1<=U,V<=N ), describing a bidirectional edge (U, V).
 

 

Output
For each test case, please output one integer representing minimal cost to transform the tree to a cycle.
 

 

Sample Input
1 4 1 2 2 3 2 4
 

 

Sample Output
3
Hint
In the sample above, you can disconnect (2,4) and then connect (1, 4) and (3, 4), and the total cost is 3.
 

 

Source
 

 

Recommend
liuyiding   |   We have carefully selected several similar problems for you:  5867 5866 5865 5864 5863 
 
/*
每个节点如果有两个或两个以上结点,就将它先于父节点断开,然后在与子节点断开,全部断开之后,和子节点自称一条直链,最后将所有的子链连城一条
直线一个结点有sum个子结点,断开是需要sum-2次操作,连接时需要sum-2次操作,这样一个结点就会进行2*(sum-2)次操作,这时加上断开父节点,一共
进行了2*(sum-2)+1次操作,构成直链之后还需要和父节点连接,这样就一共是2*(sum-1)次操作,如果这个结点是刚开始的结点,那么就不用考虑父节
点,这样操操作就是2*(sum-2)次
*/
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#define N 1000009
using namespace std;
int t,n;
vector<int > edge[N];
int ans=0;
bool dfs(int u,int p)//返回你搜到的是不是u的子树
{
    //cout<<"ans="<<ans<<endl;
    int sum=0;
    for(int i=0;i<edge[u].size();i++)
    {
        int v=edge[u][i];//下一步
        if(v==p) continue;//下一步走过了,就不要走了
        sum+=dfs(v,u);
        //visit[v]=true;
        //cout<<sum<<endl;
    }
    if(sum>=2)
    {
        if(u==1)
            ans+=2*(sum-2);
        else
            ans+=2*(sum-1);
        return false;
    }
    return true;
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        ans=0;
        int from,to;
        for(int i=0;i<=n;i++)
            edge[i].clear();
        for(int i=0;i<n-1;i++)
        {
            scanf("%d%d",&from,&to);
            //cout<<from<<" "<<to<<endl;
            edge[from].push_back(to);
            edge[to].push_back(from);
        }//建树
        dfs(1,-1);
        printf("%d\n",ans+1);
    }
    return 0;
}

 

posted @ 2016-08-22 15:52  勿忘初心0924  阅读(192)  评论(0编辑  收藏  举报