您的位置:首页 > 其它

[poj 1947]树dp+背包问题

2017-08-30 16:17 411 查看
题目链接:http://poj.org/problem?id=1947

看了很多题解都是直接一遍dfs就搞定的方法,但是我实在是没看懂那个转移方程。最后在茫茫博客中终于发现了一个有逻辑的方法,但是复杂度好像要高一些,但是还是把这个题过了。http://www.chongchonggou.com/g_91242661.html

#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;

const int maxn=155;
vector<int> G[maxn];

const int INF=0x3f3f3f3f;
int dp[2][maxn];
int f[maxn][maxn];
int res[maxn][maxn];

void dfs(int u,int fa)
{
if (G[u].size()==0)
{
f[u][0]=f[u][1]=0;
if (fa==-1) res[u][0]=res[u][1]=0;
else res[u][0]=res[u][1]=1;
}
else
{
for (int i=0;i<G[u].size();i++)
{
int v=G[u][i];
dfs(v,u);
}
memset(dp,INF,sizeof(dp));
dp[0][0]=0;
for (int i=1;i<=G[u].size();i++)
{
for (int j=0;j<=150;j++)
{
dp[i&1][j]=INF;
for (int k=0;k<=j;k++)
{
dp[i&1][j]=min(dp[i&1][j],dp[i&1^1][j-k]+f[G[u][i-1]][k]+(k==0));
}
}
}
f[u][0]=0;
if (fa==-1) res[u][0]=0;
else res[u][0]=1;
for (int i=1;i<=150;i++) f[u][i]=dp[G[u].size()&1][i-1];
for (int i=1;i<=150;i++) res[u][i]=f[u][i]+(fa!=-1);
}
}

int main()
{
memset(f,INF,sizeof(f));
memset(res,INF,sizeof(res));
int n,P;
scanf("%d%d",&n,&P);
for (int i=1;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
}
dfs(1,-1);
int ans=INF;
for (int i=1;i<=n;i++) ans=min(ans,res[i][P]);
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: