zoukankan      html  css  js  c++  java
  • 刷题总结——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;
    }
  • 相关阅读:
    Linux下文件的基本操作
    conpot_usage简要说明
    const声明常量以及特点
    let变量声明以及声明特性
    盒子模型
    文本样式
    行间距
    字体的其他样式
    字体分类
    字体样式
  • 原文地址:https://www.cnblogs.com/AseanA/p/7727962.html
Copyright © 2011-2022 走看看