hdu4714树形DP+贪心(乱搞)

Tree2cycle
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.

InputThe 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). 
OutputFor 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.


题解:
  

  


题解:

  对于子节点,如果有两个子节点,那么就要分开,分开子孙和祖先是一样的。
 对于根节点,取两个子孙连起来,将其它节点分开。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<cstdlib>
 7 #define N 1000007
 8 using namespace std;
 9 
10 int tot,head[N],Next[N*2],info[N*2];
11 int dp[N];
12 
13 void init()
14 {
15     memset(head,-1,sizeof head);
16     memset(dp,0,sizeof dp);
17     tot=0;
18 }
19 void add(int fr,int to)
20 {
21     Next[tot]=head[fr];
22     info[tot]=to;
23     head[fr]=tot++;
24 }
25 bool dfs(int u,int f)
26 {
27     int ans=0;
28     for(int i=head[u];i!=-1;i=Next[i])
29     {
30         int v=info[i];
31         if(v==f) continue;
32         if(dfs(v,u)) dp[u]+=dp[v]+1;
33         else
34         {
35                dp[u]+=dp[v];
36             ans++;
37         }
38     }
39     if(ans==0||ans==1) return false;
40        if(ans>2) dp[u]+=ans-2;
41     return true;
42 }
43 int main()
44 {
45     int cas;
46     scanf("%d",&cas);
47     while(cas--)
48     {
49         int n;
50         scanf("%d",&n);
51         init();
52         for(int i=1,x,y=1;i<n;i++)
53         {
54             scanf("%d%d",&x,&y);
55             add(x,y),add(y,x);
56         }
57         dfs(1,-1);
58         printf("%d\n",dp[1]*2+1);
59     }
60 }

 



转载于:https://www.cnblogs.com/fengzhiyuan/p/7700912.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值