hdu4714 树形dp
2016-09-19 21:22
337 查看
Tree2cycle
Time Limit: 15000/8000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others)Total Submission(s): 2218 Accepted Submission(s): 526
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
2013 ACM/ICPC Asia Regional Online —— Warmup
题意:给定一棵树,问最少要删除 添加 几次边可以使该树变成一个环;
每次都将儿子节点变成一条链。
![](http://cdn.acmerblog.com/img/1447908368913.jpg)
给个样例。 黑线表示操作数。 黑线与红线相交表示删除该红线。 两节点的黑线表示, 添加一条边。
得到如图:
![](http://cdn.acmerblog.com/img/1447908369133.jpg)
也就是说,
如果该节点有二个以上(包括二个)的分叉, 那么就首先与父亲断离,形成一条游离链。 还需要断离 sum – 2个儿子, 并且再次连接 sum – 2个儿子构成一条直链。
这里已经花费了 2 * (sum – 2) + 1次操作。 还需要一次操作是与下一个游离链相连。 即 2 * (sum – 1) 次操作。
如果该节点就是自定义的根节点, 那么其无需与父亲断离, 也无需与下一个游离链相连。 即需要 2 * (sum – 2)次操作。
每次与父亲断离后。 父亲就失去一个儿子节点。
如果该节点只有一个分叉或者是叶子节点, 什么都不管, 返回true. 表示 还是原树一起。
然后再 + 1就会构成一个环。
计算sum值呢,要进行深搜,从底层向上进行计算,当该节点与父亲节点断开连接后,那么父亲节点分叉要减1,所以计算当前分叉个数时要减去儿子中分叉个数大于等于2的,
AC代码:
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #include <vector> #include <queue> using namespace std; const int maxn=2000100; int in[maxn],vis[maxn]; struct Edge { int v,next; } edge[maxn*2]; int tot,head[maxn]; void init() { tot=0; memset(head,-1,sizeof(head)); } void add_edge(int u,int v) { edge[tot].v=v; edge[tot].next=head[u]; head[u]=tot++; } int ans; int son[maxn]; int dfs(int u,int pre) { int v,sum=0; for(int i=head[u]; i!=-1; i=edge[i].next) { v=edge[i].v; if(v==pre) continue; sum+=dfs(v,u); } son[u]=sum; if(sum>=2) { if(u==1) ans+=(sum-2)*2; else ans+=(sum-1)*2; return 0; } return 1; } int main() { int t,n,u,v; scanf("%d",&t); while(t--) { scanf("%d",&n); init(); for(int i=1; i<n; i++) { scanf("%d%d",&u,&v); add_edge(u,v); add_edge(v,u); } ans=0; dfs(1,1); for(int i=1;i<=n;i++) { cout<<son[i]<<" "; } cout<<endl; printf("%d\n",ans+1); } return 0; } /** 8 1 2 1 3 1 4 2 5 2 6 4 7 4 8 10 1 2 2 3 2 4 2 5 3 6 3 7 7 8 7 9 7 10 */
相关文章推荐
- hdu 4714 树形DP
- hdu 4714(树形dp)
- 树形dp-hdu-4714-Tree2cycle
- hdu 4714 (树形dp)
- HDU 4714 Treecycle(树形dp)
- hdu_4714_Tree2cycle(树形DP)
- HDU 4714 Tree2cycle (树形DP)
- hdu 4714 (树形dp)
- HDU 4714 Tree2cycle (树形DP)
- HDU-4714-树形dp
- HDU 4714 Tree2cycle(树形dp)
- hdu_4714_Tree2cycle(树形DP)
- 树形dp-hdu-4714-Tree2cycle
- hdu 4714(树形dp)
- HDU 4714 Tree2cycle (构造,树形DP)
- HDU 1011 Starship Troopers(树形DP)
- hdu 2412 Party at Hali-Bula (树形DP)
- hdu 2415 Bribing FIPA(树形DP)
- HDU 1561 The more, The Better【树形DP】
- HDU 1520 Anniversary party【树形DP】