• pku1848 Tree


    http://poj.org/problem?id=1848

    DP, 树状DP

    一个节点形成环的过程中只有3种状态,

    0:有0条边连着这个点

    1:有1条边连着这个点

    2:有2条边连着这个点

    转移还可以再优化,不过不太好写,直接上3层循环。。。

    代码中inf的定义:至少要添无穷多个边,才可以满足要求   ---等价于--->   添多少都没用

      1 #include <stdio.h>
      2 #include <vector>
      3 #define N 123
      4 
      5 using namespace std;
      6 
      7 vector<int> a[N];
      8 int mark[N], dp[N][3];
      9 const int inf = 1234;
     10 
     11 int min(int x, int y)
     12 {
     13     return x<y? x: y;
     14 }
     15 
     16 int limit_inf(int x)
     17 {
     18     return x>inf? inf: x;
     19 }
     20 
     21 int f(int x, vector<int> b)
     22 {
     23     int i, j, k, sum1, min1;
     24     
     25     //0
     26     sum1 = 0;
     27     for(i=0; i<b.size(); i++)
     28     {
     29         sum1 += dp[b[i]][2];
     30     }
     31     dp[x][0] = limit_inf(sum1);
     32 
     33     //1
     34     min1 = inf;
     35     for(i=0; i<b.size(); i++)
     36     {
     37         sum1 = min(dp[b[i]][0], dp[b[i]][1]);
     38         for(j=0; j<b.size(); j++)
     39         {
     40             if(j != i)
     41             {
     42                 sum1 += dp[b[j]][2];
     43             }
     44         }
     45         min1 = min(min1, sum1);
     46     }
     47     dp[x][1] = limit_inf(min1);
     48 
     49     //2
     50     min1 = inf;
     51     for(i=0; i<b.size(); i++)
     52     {
     53         for(j=0; j<b.size(); j++)
     54         {
     55             if(j != i)
     56             {
     57                 sum1 = min(dp[b[i]][0], dp[b[i]][1]) + 1;
     58                 sum1 += min(dp[b[j]][0], dp[b[j]][1]);
     59                 for(k=0; k<b.size(); k++)
     60                 {
     61                     if((k != i) && (k != j))
     62                     {
     63                         sum1 += dp[b[k]][2];
     64                     }
     65                 }
     66                 min1 = min(min1, sum1);
     67             }
     68         }
     69     }
     70     for(i=0; i<b.size(); i++)
     71     {
     72         sum1 = dp[b[i]][1] + 1;
     73         for(j=0; j<b.size(); j++)
     74         {
     75             if(j != i)
     76             {
     77                 sum1 += dp[b[j]][2];
     78             }
     79         }
     80         min1 = min(min1, sum1);
     81     }
     82     dp[x][2] = limit_inf(min1);
     83     return 0;
     84 }
     85 
     86 int dfs(int x)
     87 {
     88     int i, j;
     89     vector<int> b;
     90     b.clear();
     91     //printf("(%d: ", x);
     92     for(i=0; i<a[x].size(); i++) 
     93     {
     94         j = a[x][i];
     95         if(mark[j] == 0)
     96         {
     97             b.push_back(j);
     98             mark[j] = 1;
     99             dfs(j);
    100         }
    101     }
    102     //printf(" ) ");
    103     return f(x, b);
    104 }
    105 
    106 int main()
    107 {
    108     int n, i, x, y;
    109     while(~scanf("%d", &n))
    110     {
    111         for(i=1; i<=n; i++)
    112         {
    113             dp[i][0] = dp[i][1] = dp[1][2] = inf;
    114             mark[i] = 0;
    115             a[i].clear();
    116         }
    117         for(i=1; i<=n-1; i++)
    118         {
    119             scanf("%d%d", &x, &y);
    120             a[x].push_back(y);
    121             a[y].push_back(x);
    122         }
    123         mark[1] = 1;
    124         dfs(1);
    125         if(dp[1][2] == inf)
    126         {
    127             dp[1][2] = -1;
    128         }
    129         printf("%d\n", dp[1][2]);
    130         /*
    131         for(i=1; i<=n; i++)
    132         {
    133             printf("%5d %5d %5d\n", dp[i][0], dp[i][1], dp[i][2]);
    134         }
    135         */
    136     }
    137     return 0;
    138 }
  • 相关阅读:
    asp.net控件开发基础(转)
    如何在C#中直接操作C++结构体(转)
    如何打造自己的代码段
    WeifenLuo.WinFormsUI.Docking.dll 源码分析(一)
    软件竞标流程与要点【转】
    C#进制转换
    使用 DpaToolkit 对 C#类库进行反向建模
    算法的时间复杂度(计算实例)
    C#操作SQLServer的Image字段
    不同进制之间的转换
  • 原文地址:https://www.cnblogs.com/yuan1991/p/pku1848.html
Copyright © 2020-2023  润新知