zoukankan      html  css  js  c++  java
  • POJ1947 Rebuilding Roads

    Description

    The cows have reconstructed Farmer John's farm, with its N barns (1 <= N <= 150, number 1..N) after the terrible earthquake last May. The cows didn't have time to rebuild any extra roads, so now there is exactly one way to get from any given barn to any other barn. Thus, the farm transportation system can be represented as a tree. 

    Farmer John wants to know how much damage another earthquake could do. He wants to know the minimum number of roads whose destruction would isolate a subtree of exactly P (1 <= P <= N) barns from the rest of the barns.

    Input

    * Line 1: Two integers, N and P 

    * Lines 2..N: N-1 lines, each with two integers I and J. Node I is node J's parent in the tree of roads. 

    Output

    A single line containing the integer that is the minimum number of roads that need to be destroyed for a subtree of P nodes to be isolated. 

    Sample Input

    11 6
    1 2
    1 3
    1 4
    1 5
    2 6
    2 7
    2 8
    4 9
    4 10
    4 11
    

    Sample Output

    2

    Hint

    [A subtree with nodes (1, 2, 3, 6, 7, 8) will become isolated if roads 1-4 and 1-5 are destroyed.] 

    Source

    正解:树形DP

    解题报告:

      感觉自己DP很萎,最近练一下DP。

      f[i][j]记录以i为根结点的子树切出j个节点的最小代价,转移的话也很简单,f[x][j] = min{f[x][j],f[son[x][i]][k]+f[x][j-k]-2},减2是因为要减去算了两次的x到son[x][i]的那条边。

      递归转移就可以了。

      题解传送门:http://www.cnblogs.com/celia01/archive/2012/08/02/2619063.html

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<algorithm>
     7 #include<vector>
     8 using namespace std;
     9 const int MAXN = 151;
    10 int f[MAXN][MAXN];//f[i][j]记录以i为根结点的子树切出j个节点的最小代价
    11 int du[MAXN];
    12 vector<int>w[MAXN];
    13 int n,p;
    14 int ans;
    15 int root;
    16 
    17 inline int getint(){
    18     char c=getchar(); int w=0,q=0;
    19     while(c!='-' && ( c<'0' || c>'9')) c=getchar();
    20     if(c=='-') c=getchar(),q=1;
    21     while(c>='0' && c<='9') w=w*10+c-'0',c=getchar();
    22     return q?-w:w;
    23 }
    24 
    25 inline void dfs(int x){
    26     if(x==root) f[x][1]=w[x].size();
    27     else f[x][1]=w[x].size()+1;//父边
    28 
    29     for(int i=0;i<w[x].size();i++) dfs(w[x][i]);
    30 
    31     for(int i=0;i<w[x].size();i++) 
    32     for(int j=p;j>=0;j--)
    33         for(int k=0;k<=j;k++) {
    34         if(f[x][k]!=MAXN && f[w[x][i]][j-k]) {
    35             f[x][j]=min(f[x][j],f[x][k]+f[w[x][i]][j-k]-2);
    36         }
    37         }       
    38 }
    39 
    40 int main()
    41 {
    42     n=getint(); p=getint();
    43     
    44     int x,y;
    45     for(int i=1;i<n;i++) {
    46     x=getint(); y=getint();
    47     w[x].push_back(y); du[y]++;
    48     }
    49 
    50     for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) f[i][j]=MAXN;
    51 
    52     for(int i=1;i<=n;i++) if(du[i]==0) { root=i; dfs(i); break; }
    53 
    54     ans=MAXN;
    55     for(int i=1;i<=n;i++) ans=min(ans,f[i][p]);
    56 
    57     printf("%d",ans);
    58 
    59     return 0;
    60 }
  • 相关阅读:
    linux内存的使用与page buffer (转)
    基于linux2.6.38.8内核的SDIO/wifi驱动分析(转)
    RamDisk块设备驱动实例开发讲解一
    Linux加密框架设计与实现(转)
    v4l2子系统学习心得
    一句memset引发的疑案
    linux 信号量之SIGNAL 0(转)
    可重入函数
    从ARM VIVT看linux的cache 处理
    内核抢占与preempt_count
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/5574523.html
Copyright © 2011-2022 走看看