刷题总结——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. 

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;
}
原文地址:https://www.cnblogs.com/AseanA/p/7727962.html