刷题总结——Tree2cycle(hdu4714 树形dp)
题目:
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.
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.
题目大意:给定一棵树··问将这棵树变成环的最小价值
题解:
原本以为是道很难的题··结果发现自己智障了···
首先将树剖成链···对于每个节点··如果有2个以上的儿子··需要将儿子节点断开到只剩2个··再将该节点与父亲节点断开···否则直接与父亲节点相连··每剖一次代价加1··最后合并链的时候代价*2+1(+1是因为首位链要合并)··
递归求解答案即可··
代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<cstring> #include<string> #include<algorithm> using namespace std; const int N=1e6+5; inline int R() { char c;int f=0; for(c=getchar();c<'0'||c>'9';c=getchar()); for(;c<='9'&&c>='0';c=getchar()) f=(f<<3)+(f<<1)+c-'0'; return f; } int n,ans=0,first[N],nxt[N*2],go[N*2],tot,T; inline void pre() { memset(first,0,sizeof(first));ans=tot=0; } inline void comb(int a,int b) { nxt[++tot]=first[a],first[a]=tot,go[tot]=b; nxt[++tot]=first[b],first[b]=tot,go[tot]=a; } inline int dfs(int u,int fa) { int cnt=0; for(int e=first[u];e;e=nxt[e]) {int v=go[e];if(v==fa) continue;cnt+=dfs(v,u);} if(cnt>=2){ans+=cnt-2+(u==1?0:1);return 0;} else return 1; } int main() { // freopen("a.in","r",stdin); T=R(); while(T--) { pre();n=R();int a,b; for(int i=1;i<n;i++) {a=R(),b=R();comb(a,b);} dfs(1,0);cout<<ans*2+1<<endl; } return 0; }