Rebuilding Roads POJ
来源:互联网 发布:可信的淘宝货源 编辑:程序博客网 时间:2024/05/29 17:03
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 61 21 31 41 52 62 72 84 94 104 11
Sample Output
2
题意就是求出从原先树上分割出包含p个点的子树的最小花费
我们随便找一个点作为根节点。然后树形DP即可。
DP[i][j]表示以i节点为根的子树包含j个点的最小花费是多少
dp初始化为
for(int i=1;i<=n;i++) dp[i][1]=du[i];
du数组表示每个节点的度数。
状态转移方程为
for(int j=p;j>=2;j--){ for(int k=j-1;k>=1;k--) { dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v][k]-2);// -2是为了除去重复的边 }}
应该可以很容易的看出 这是一个01背包问题的状态转移方程。
#include <string>#include<string.h>#include<vector>#include<queue>#include<cmath>#include<algorithm>#include<map>#include<set>#include<cstdio>#include<iostream>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define fuck(x) cout<<x<<endl#define mem(a,b) memset(a,b,sizeof a)const int MAX=1000;class e{public: int u,v,next;};e edge[MAX<<1];int head[MAX];int tot=0;void add(int u,int v){ edge[tot].u=u,edge[tot].v=v,edge[tot].next=head[u],head[u]=tot++;}void init(){ tot=0; mem(head,-1);}int du[MAX];int dp[MAX][MAX];int n,p;void init2(){ mem(dp,0x3f); mem(du,0);}void dfs(int u,int per){ dp[u][1]=du[u]; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v==per) continue; dfs(v,u); for(int j=p;j>=2;j--) { for(int k=j-1;k>=1;k--) { dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v][k]-2); } } }}int main(){ while(~scanf("%d %d",&n,&p)) { init(); init2(); for(int i=1;i<n;i++) { int u,v; scanf("%d %d",&u,&v); add(u,v); add(v,u); du[u]++; du[v]++; } for(int i=1;i<=n;i++) dp[i][1]=du[i]; dfs(1,-1); int ans=0x3f3f3f3f; for(int i=1;i<=n;i++) ans=min(dp[i][p],ans); cout<<ans<<endl; }}
阅读全文
0 0
- POJ 1947 Rebuilding Roads
- poj 1947 Rebuilding Roads
- POJ 1947 Rebuilding Roads
- POJ 1947 Rebuilding Roads
- poj 1947 Rebuilding Roads
- POJ 1947 Rebuilding Roads
- POJ 1947 Rebuilding Roads
- poj-1947-Rebuilding Roads
- POJ 1947 Rebuilding Roads
- POJ 1947 Rebuilding Roads
- POJ 1947 Rebuilding Roads
- POJ 1947 Rebuilding Roads
- POJ 1947--Rebuilding Roads
- POJ 1947 Rebuilding Roads
- poj-1947 Rebuilding Roads
- Poj 1947 Rebuilding Roads
- POJ 1947 Rebuilding roads
- 【poj 1947】 Rebuilding Roads
- Ajax
- linux中内存泄漏的检测(二)定制化的malloc/free
- 【HNOI2015】菜肴制作 :思想 + 拓扑排序
- POJ 1873 The Fortified Forest(凸包)
- linux中内存泄漏的检测(三)定制化的new/delete
- Rebuilding Roads POJ
- ANDROID-GDAL 交叉编译
- iOS 使用信号量来处理多图片上传
- CSS-如何让img图片元素居中
- 从AtomicXXX稍微说一下Unsafe
- 苹果手机的z-index 无效的问题
- 程序
- Error opening file: /sdcard/screenshot.png (Read-only file system) 问题解决
- linux中内存泄漏的检测(四)记录泄漏的大小