http://blog.csdn.net/woshi250hua/article/details/7632785
这道题我一开始想的dp[i][j],i是节点,j是删除的点数,dp是最少删边的个数,然而状态转移方程不太好想。
而题解其实差不多,只不过j为剩余点的个数
这样我们就有最初状态,dp[i][1] = 子节点个数,而dp[i][j]就可以从子节点的状态推出来
dp[i][j] = min(dp[i][j],dp[i][k]-1+dp[s][j-k]) (1<=i<=n,2<=j<=sum(节点总和),1<=k<j,s为i子节点)(i中已有k个节点并从s中选择j-k个,算最少删除边数,s选上所以i->s的边不需删除,所以-1)
#include <iostream> #include <string> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm> #include <stack> #include <queue> #include <cctype> #include <vector> #include <iterator> #include <set> #include <map> #include <sstream> using namespace std; #define mem(a,b) memset(a,b,sizeof(a)) #define pf printf #define sf scanf #define spf sprintf #define pb push_back #define debug printf("! ") #define MAXN 1010 #define MAX(a,b) a>b?a:b #define blank pf(" ") #define LL long long #define ALL(x) x.begin(),x.end() #define INS(x) inserter(x,x.begin()) #define pqueue priority_queue #define INF 0x3f3f3f3f int n,m; struct node { int y,next; }tree[1050]; int head[505],dp[505][505],ptr=1; int sum[505],vl[505],vis[505]; void add(int x,int y) { tree[ptr].y = y; tree[ptr].next = head[x]; head[x] = ptr++; } void dfs(int root) { if(vis[root]) return; int i,j,k; vis[root] = sum[root] = 1; int tot = 0; for(i=head[root]; i!=-1; i=tree[i].next) { int p = tree[i].y; if(!vis[p]) { dfs(p); sum[root]+=sum[p]; tot++; //pf("i%d p%d tot%d sum%d ",root,p,tot,sum[root]); } } dp[root][1] = tot; for(i=head[root]; i!=-1; i=tree[i].next) { int p = tree[i].y; for(j = sum[root];j>1;j--) { for(k = 1;k<j;k++) { if(dp[root][k]!=INF && dp[p][j-k]!=INF) { dp[root][j] = min(dp[root][j],dp[root][k]+dp[p][j-k]-1); //pf("i%d j%d k%d p%d dp%d ",root,j,k,p,dp[root][j]); } } } } } int main() { int i,j,k,a,b; while(~sf("%d%d",&n,&m) && m+n>0) { mem(head,-1); ptr = 1; for(i=1;i<=n-1;i++) { sf("%d%d",&a,&b); add(a,b); add(b,a); } mem(dp,INF); mem(vis,0); dfs(1); int ans = INF; for (i = 1; i <= n; ++i) { if (i == 1) ans = min(ans,dp[i][m]); else ans = min(ans,dp[i][m]+1);//非根节点要删除连到父亲节点的那条边 } printf("%d ",ans); } return 0; }