Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 9249 | Accepted: 4198 |
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
#include <iostream> #include <cstring> #include <cstdio> using namespace std; #define INF 0x7ffffff #define N 155 struct Edge { int to,next; }edge[N*N/2]; int head[N],tot; int n,m; int f[N]; int dp[N][N]; void add(int x,int y) { edge[tot].to=y; edge[tot].next=head[x]; head[x]=tot++; } void dfs(int u) { int i,j,k; for(j=0;j<=m;j++) { dp[u][j]=INF; } dp[u][1]=0; for(i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].to; dfs(v); for(j=m;j>=0;j--) { for(k=0;k<j;k++) { if(k) dp[u][j] = min(dp[u][j],dp[u][j-k]+dp[v][k]); else dp[u][j] = dp[u][j]+1; } } } } void init() { tot=0; memset(f,-1,sizeof(f)); memset(head,-1,sizeof(head)); } int main() { int i; while(scanf("%d%d",&n,&m), n||m) { init(); for(i=1;i<n;i++) { int a,b; scanf("%d%d",&a,&b); add(a,b); f[b]=a; } int root=1; while(f[root]!=-1) { root=f[root]; } dfs(root); int ans=dp[root][m]; for(i=1;i<=n;i++) //除了根节点,其他节点要想成为独立的根,必先与父节点断绝关系,所以要先加1 { ans=min(ans,dp[i][m]+1); } printf("%d\n",ans); } return 0; }
树形DP [POJ 1947] Rebuilding Roads
原文:http://www.cnblogs.com/hate13/p/4095561.html