标签:
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 11334 | Accepted: 5222 |
Description
Input
Output
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
Source
给你一棵有n个节点的树,可以砍掉其中一些边,问最少砍几条边可以留下一个有p个节点的树(剩下的必须是一整棵树)
标准树形DP
1 /*by SilverN*/ 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<vector> 8 using namespace std; 9 const int mxn=160; 10 int read(){ 11 int x=0,f=1;char ch=getchar(); 12 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 13 while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 14 return x*f; 15 } 16 int n,p; 17 int f[mxn][mxn]; 18 int num[mxn]; 19 vector<int>e[mxn]; 20 void dp(int u){ 21 int i,j,k; 22 num[u]=1; 23 if(!e[u].size()){f[u][1]=0;return;} 24 for(i=0;i<e[u].size();i++){ 25 int v=e[u][i]; 26 dp(v); 27 num[u]+=num[v]; 28 for(j=num[u];j;j--){ 29 for(k=1;k<j;k++){ 30 f[u][j]=min(f[u][j],f[u][j-k]+f[v][k]-1); 31 } 32 } 33 } 34 return; 35 } 36 int main(){ 37 n=read();p=read(); 38 int i,j; 39 int u,v; 40 for(i=1;i<n;i++){ 41 u=read();v=read(); 42 e[u].push_back(v); 43 num[u]++; 44 } 45 memset(f,0x3f,sizeof f); 46 for(i=1;i<=n;i++){ 47 f[i][1]=num[i]; 48 } 49 dp(1); 50 int ans=f[1][p]; 51 for(i=1;i<=n;i++){ 52 ans=min(ans,f[i][p]+1); 53 } 54 printf("%d\n",ans); 55 return 0; 56 }
标签:
原文地址:http://www.cnblogs.com/SilverNebula/p/5918273.html