zoukankan      html  css  js  c++  java
  • POJ 1947 Rebuilding Roads

    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.] 
    题意:
    有n个点组成一棵树,问至少要删除多少条边才能获得一棵有p个结点的子树?
    一道转移比较有意思的树形dp题。
    树上的状态应该比较明确。dp[i][j]表示以i为根有j个节点的子树。
    转移怎么办?
    把它的子树编成1,2..x。
    每个子树取几个或不取达到j-1(自己有1个节点)。
    我们好像又能搞出一个dp,
    dp_[i][j]表示前i个子树取了j个节点。
    有dp_[i][j]=min{dp_[i-1][k]+dp[i][j-k]-2};(添加一条边要减2);
    还有dp_[i][j]=min{dp[i-1][k]};
    倒着枚举j。
    可以变成:
    dp_[j]=min(dp_[j],dp_[j-k]+dp[i][j-k]-2);
    直接放在原数组上做:
            for (int j=m;j>1;j--){
                for (int k=1;k<j;k++){
                    dp[u][j]=min(dp[u][j],dp[u][k]+dp[v[i]][j-k]-2);
                }
            }

    代码:

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<cstdlib>
     7 #include<vector>
     8 using namespace std;
     9 typedef long long ll;
    10 typedef long double ld;
    11 typedef pair<int,int> pr;
    12 const double pi=acos(-1);
    13 #define rep(i,a,n) for(int i=a;i<=n;i++)
    14 #define per(i,n,a) for(int i=n;i>=a;i--)
    15 #define Rep(i,u) for(int i=head[u];i;i=Next[i])
    16 #define clr(a) memset(a,0,sizeof(a))
    17 #define pb push_back
    18 #define mp make_pair
    19 #define fi first
    20 #define sc second
    21 #define pq priority_queue
    22 #define pqb priority_queue <int, vector<int>, less<int> >
    23 #define pqs priority_queue <int, vector<int>, greater<int> >
    24 #define vec vector
    25 ld eps=1e-9;
    26 ll pp=1000000007;
    27 ll mo(ll a,ll pp){if(a>=0 && a<pp)return a;a%=pp;if(a<0)a+=pp;return a;}
    28 ll powmod(ll a,ll b,ll pp){ll ans=1;for(;b;b>>=1,a=mo(a*a,pp))if(b&1)ans=mo(ans*a,pp);return ans;}
    29 void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
    30 //void add(int x,int y,int z){ v[++e]=y; next[e]=head[x]; head[x]=e; cost[e]=z; }
    31 int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1};
    32 ll read(){ ll ans=0; char last=' ',ch=getchar();
    33 while(ch<'0' || ch>'9')last=ch,ch=getchar();
    34 while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    35 if(last=='-')ans=-ans; return ans;
    36 }
    37 const int M=1000,N=200,inf=1e09;
    38 int n,m;
    39 int v[M],Next[M],head[N],e,dp[N][N],du[N];
    40 void add(int x,int y){ v[++e]=y; Next[e]=head[x]; head[x]=e;}
    41 void dfs(int u,int fa){
    42     for (int i=head[u];i;i=Next[i])
    43     if (v[i]!=fa){
    44         dfs(v[i],u);
    45         for (int j=m;j>1;j--){
    46             for (int k=1;k<j;k++){
    47                 dp[u][j]=min(dp[u][j],dp[u][k]+dp[v[i]][j-k]-2);
    48             }
    49         }
    50     }
    51 }
    52 int main(){
    53     n=read(),m=read();
    54     for (int i=1;i<n;i++) {
    55         int a=read(),b=read();
    56         add(a,b); add(b,a);
    57         du[a]++; du[b]++;
    58     }
    59     for (int i=1;i<=n;i++){
    60         dp[i][1]=du[i];
    61         for (int j=2;j<=m;j++) 
    62             dp[i][j]=inf;
    63     }
    64     dfs(1,0);
    65     int ans=inf;
    66     for (int i=1;i<=n;i++)
    67         ans=min(ans,dp[i][m]);
    68     printf("%d",ans);
    69     return 0;
    70 } 
    View Code
  • 相关阅读:
    单片机课程设计——基于51单片机温湿度检测系统的设计与实现
    CC2530微处理器接口开发技术——信号灯的设计与实现
    ACM菜鸡退役帖——ACM究竟给了我什么?
    JAVA课程设计——一个简单的教务人事管理系统
    嵌入式系统及应用课程设计——基于STM32的温湿度监测系统
    Web前端课程设计——个人主页
    如何快速使用Access实现一个登录验证界面?
    2018亚洲区域赛青岛站参赛总结
    2018亚洲区域赛焦作站参赛总结
    2018 ACM-ICPC Asia Beijing Regional Contest (部分题解)
  • 原文地址:https://www.cnblogs.com/SXia/p/7641038.html
Copyright © 2011-2022 走看看