poj1947(树形dp)
src:http://poj.org/problem?id=1947
ac代码:
#include <iostream> #include<cstdlib> #include<algorithm> #include<cmath> #include<functional> #include<utility> #include<string> #include<string.h> #include<vector> #include<iomanip> #include<stack> using namespace std; #define FOR(i,a,b) for(int i=a;i<=b;i++) #define Max(a,b) a=max(a,b) #define Min(a,b) a=min(a,b) const int inf=99999999; int n,p,dp[151][151],sz[151],num[151]; vector<int>head[151];//sz[]表示树u有几个结点,num[]表示有个子节点 void init(){FOR(i,1,n)FOR(j,1,n)dp[i][j]=inf;FOR(i,1,n)head[i].clear();memset(sz,0,sizeof(sz));memset(num,0,sizeof(num));} void add_edge(int u,int v){head[u].push_back(v);} void dfs1(int u,int fa) { sz[u]=1; for(int i=0;i<head[u].size();i++){ int v=head[u][i]; if(v==fa)continue; dfs1(v,u); num[u]++; sz[u]+=sz[v]; } } void dfs2(int u,int fa) { dp[u][1]=num[u]; for(int i=0;i<head[u].size();i++){ int v=head[u][i]; if(v==fa)continue; dfs2(v,u); for(int j=sz[u];j>=2;j--)for(int k=1;k<=sz[v];k++)if(j>k){ Min(dp[u][j],dp[u][j-k]+dp[v][k]-1); } } } int main() { ios::sync_with_stdio(false); while(cin>>n>>p){ init(); int a,b; FOR(i,1,n-1){cin>>a>>b;add_edge(a,b);add_edge(b,a);} dfs1(1,-1); dfs2(1,-1); int ans=dp[1][p]; FOR(i,2,n)Min(ans,dp[i][p]+1); cout<<ans<<endl; } return 0; }

浙公网安备 33010602011771号