本文主要是介绍树形DP(4) Poj1947 Rebuilding Roads,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目链接:http://poj.org/problem?id=1947
Rebuilding Roads
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 8566 | Accepted: 3835 |
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.
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.
* 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。
/*
求减去ans条边,剩下p个结点,求最小的ans;
dp[s][i]:记录s结点,要得到一棵j个节点的子树去掉的最少边数考虑其儿子k1)如果不去掉k子树,则dp[s][i] = min(dp[s][j]+dp[k][i-j]) 0 <= j <= i2)如果去掉k子树,则dp[s][i] = dp[s][i]+1总的为dp[s][i] = min (min(dp[s][j]+dp[k][i-j]) , dp[s][i]+1 )
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
vector<int>vct[155];
bool vis[155];
int dp[155][155];
int n,p;
void solve(int u)
{vis[u] = 1;int v;for (int i = 0; i <= p; i++)dp[u][i] = n;dp[u][1] = 0; //leaf node//if(vct[u].size()==0)dp[u][1]=0;for (int x = 0; x < vct[u].size(); x++){v = vct[u][x];if(!vis[v]){solve(v);for(int i=p;i>=1;i--){int Min = dp[u][i]+1;for (int j = 1; j < i; j++)Min = min(dp[u][j]+dp[v][i-j],Min);dp[u][i] = Min;}}}
}
int main()
{int u,v;while(~scanf("%d%d",&n,&p)){memset(vis,false,sizeof(vis));for (int i = 1; i <= n; i++)vct[i].clear();for (int i = 1; i < n; i++){scanf("%d%d",&u,&v);vct[u].push_back(v);}solve(1);int ans = dp[1][p];for (int i = 1; i <= n; i++)ans = min(ans,dp[i][p]+1);printf("%d\n",ans);}return 0;
}
这篇关于树形DP(4) Poj1947 Rebuilding Roads的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!