HDU-4714-贪心

Tree2cycle

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


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
       求将一棵树拆分为一个环的最小的代价,可以拆解边和增加边,代价都是1.
     换一下思路,就是把这棵树拆掉det条边形成了det+1条链,再添加det+1条边,总代价就是det*2+1;我们只要求出最小的det就ok了。
对于节点u它可能有一个或多个儿子,如果只有一个儿子的话那就是一条链,不用再管,如果有son个儿子(son>1),我们需要拆掉son-1条边才能保证拆分成链,问题在于应该怎么拆掉这son-1条链才能最优。
            fa           
             |
    u
    /  |      
      v1  v2   v3
    对于上面这棵树,我们可以选择拆掉u-v2和u-v3或者是u-fa和u-v1,也就是删掉两个儿子或者一个儿子和一个父亲,会发现后者其实更优,因为避免了父亲形成多儿子的情况,就减少了删除的边数。知道这点就很容易了,递归返回儿子数目即可。
    
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 using namespace std;
 6 #define inf 0x3f3f3f3f
 7 #pragma comment(linker, "/STACK:102400000,102400000")
 8 int first[1000010],tot;
 9 struct Edge
10 {
11     int v,next;
12 }e[2001000];
13 void add(int u,int v){
14     e[tot].v=v;
15     e[tot].next=first[u];
16     first[u]=tot++;
17 }
18 int aaa;
19 int dfs(int u,int fa)
20 {
21     int s=0;
22     for(int i=first[u];~i;i=e[i].next){
23         int v=e[i].v;
24         if(v==fa) continue;
25         s+=dfs(v,u);
26     }
27     if(s>1){
28         aaa+=s-1;
29         if(u==1) aaa--;
30         return 0;
31     }
32     else {
33         return 1;
34     }
35 }
36 int main()
37 {
38     int n,i,j,k,u,v;
39     int t;
40     cin>>t;
41     while(t--){aaa=0;
42         memset(first,-1,sizeof(first));
43         tot=0;
44         scanf("%d",&n);
45         for(i=1;i<n;++i){
46             scanf("%d%d",&u,&v);
47             add(u,v);
48             add(v,u);
49         }
50         dfs(1,0);
51         cout<<aaa+aaa+1<<endl;
52     }
53     return 0;
54 }
原文地址:https://www.cnblogs.com/zzqc/p/8872420.html