zoukankan      html  css  js  c++  java
  • HDU 4714 Tree2cycle DP 2013杭电热身赛 1009

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4714

    Tree2cycle

    Time Limit: 15000/8000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)
    Total Submission(s): 400    Accepted Submission(s): 78

    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
     
    题目大意:已知一棵树,切边与连边都需要1的cost。现在要把这棵树分割连接成为一个环,求最小cost。
     
    解题思路:将整棵树拆成N个单枝(所有点的度小于2),所需的cost即为2*N-1(拆成N个单枝需 N-1 cost,合成一个环需要 N cost)。
    可用树形DP求出N最小的情况,用dp[i][j]表示以i为根的可用度为j的最小单枝数。
    状态转移方程:dp[root][0]=min(dp[root][0]+dp[son][0],dp[root][1]+dp[son][1]-1)
           dp[root][1]=min(dp[root][1]+dp[son][0],dp[root][2]+dp[son][1]-1)
           dp[root][2]=dp[root][2]+dp[son][0]
    P.S. 该题的数据量较大,要加#pragma comment(linker,"/STACK:1024000000,1024000000")语句,而且要用C++编译器,不能用G++。
     
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #pragma comment(linker,"/STACK:1024000000,1024000000")
     6 using namespace std;
     7 #define N 1000005
     8 #define M 2000010
     9 int vis[N],all,first[N],next[M],v[M],e,degree[N],dp[N][3];
    10 void addedge(int x,int y)
    11 {
    12     v[e]=y;
    13     next[e]=first[x];
    14     first[x]=e++;
    15 }
    16 void dfs(int root)
    17 {
    18     int i,k;
    19     dp[root][0]=dp[root][1]=dp[root][2]=1;
    20     vis[root]=1;
    21     for(i=first[root];i!=-1;i=next[i])
    22     {
    23         k=v[i];
    24         if(!vis[k])
    25         {
    26             dfs(k);
    27             dp[root][0]=min(dp[root][0]+dp[k][0],dp[root][1]+dp[k][1]-1);
    28             dp[root][1]=min(dp[root][1]+dp[k][0],dp[root][2]+dp[k][1]-1);
    29             dp[root][2]=dp[root][2]+dp[k][0];
    30         }
    31     }
    32 }
    33 int main()
    34 {
    35     int t,i,x,y;
    36     scanf("%d",&t);
    37     while(t--)
    38     {
    39         memset(dp,0,sizeof(dp));
    40         memset(first,-1,sizeof(first));
    41         e=0;
    42         all=0;
    43         int n;
    44         scanf("%d",&n);
    45         for(i=1;i<n;i++)
    46         {
    47             scanf("%d%d",&x,&y);
    48             addedge(x,y);
    49             addedge(y,x);
    50         }
    51         memset(vis,0,sizeof(vis));
    52         dfs(1);
    53         all=min(dp[1][0],min(dp[1][1],dp[1][2]));
    54         // cout<<all<<endl;
    55         printf("%d
    ",all*2-1);
    56     }
    57     return 0;
    58 }
    View Code

    本人入ACM时间尚短,写的不好的地方请多见谅。

  • 相关阅读:
    走线规范-标识
    python学习之网路操作
    python学习之函数
    RTT学习之软件包
    RT_THREAD之组件学习
    RT_THREAD之nano学习
    物联网相关的模块
    JavaScript学习笔记之二
    javascript完美实现图片拖动改变顺序
    响应式WEB设计的9项基本原则
  • 原文地址:https://www.cnblogs.com/wuwing/p/3308825.html
Copyright © 2011-2022 走看看