POJ 1947 树形背包
2012-09-12 16:26
134 查看
题意:将一颗树分解成若干部分,其中一个部分还有的节点为p,求实现上述操作最少要删去几条边。
做法:树形背包。确立根节点,找出各自节点的子孙数目。做这题是先把每个子树确立为一个状态,并建立状态方程:dp[u][j]=min(dp[u][j-k]+dp[v][k]),其中,j k 分别代表u,v所要删去的节点,意思是求在以u为根的一棵树中,删掉j个节点所需要的删去的边数。这里dp[u][son[u]]=0,这个算式只在u有父节点的时候成立,他的父节点构成的树,要删掉son[u]个
节点,可以只需删去链接它和u 的那一条边。还有一个问题是最终生成答案的时候要遍历每一个节点,而且除总祖先节点外,为了独立形成子树,其他节点的dp值必须加1。
做法:树形背包。确立根节点,找出各自节点的子孙数目。做这题是先把每个子树确立为一个状态,并建立状态方程:dp[u][j]=min(dp[u][j-k]+dp[v][k]),其中,j k 分别代表u,v所要删去的节点,意思是求在以u为根的一棵树中,删掉j个节点所需要的删去的边数。这里dp[u][son[u]]=0,这个算式只在u有父节点的时候成立,他的父节点构成的树,要删掉son[u]个
节点,可以只需删去链接它和u 的那一条边。还有一个问题是最终生成答案的时候要遍历每一个节点,而且除总祖先节点外,为了独立形成子树,其他节点的dp值必须加1。
#include<stdio.h> #include<string.h> #define eps 1e8 #define LMT 155 /*类似的题,先要确立根节点*/ typedef struct { int u,v,next; }line; line e[LMT<<1]; int dp[LMT][LMT],next[LMT],son[LMT]; int all,p,n; inline int min(int a,int b) { return a<b?a:b; } void insert(int u,int v) { e[all].u=u; e[all].v=v; e[all].next=next[u]; next[u]=all++; e[all].u=v; e[all].v=u; e[all].next=next[v]; next[v]=all++; } void inidfs(int u,int pre) { son[u]=1; int v,x; for(x=next[u];x!=-1;x=e[x].next) if(e[x].v!=pre) { v=e[x].v; inidfs(v,u); son[u]+=son[v]; } dp[u][son[u]]=1; dp[u][0]=0; } void dfs(int u,int pre) { int x,v,j,k; for(x=next[u];x!=-1;x=e[x].next) if(e[x].v!=pre) { v=e[x].v; dfs(v,u); for(j=son[u]-1;j>=0;j--) for(k=0;k<=son[v]&&k<=j;k++) if(dp[u][j-k]!=eps) dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v][k]); } } int main() { int i,ans,j; while(scanf("%d%d",&n,&p)!=EOF) { memset(next,-1,sizeof(next)); memset(son,0,sizeof(son)); all=0; for(i=1;i<n;i++) { int u,v; scanf("%d%d",&u,&v); insert(u,v); } for(i=1;i<=n;i++) for(j=0;j<=n;j++) dp[i][j]=eps; inidfs(1,0); dfs(1,0); ans=dp[1][son[1]-p]; for(i=2;i<=n;i++) if(son[i]>=p) ans=min(ans,dp[i][son[i]-p]+1); printf("%d\n",ans); } return 0; }
相关文章推荐
- POJ 1947 树形 DP + 分组背包
- poj 1947(树形DP+背包)
- poj 1947 树形dp 背包
- POJ 1947-Rebuilding Roads(树形背包)
- poj 1947(树形背包问题)
- poj_1947 Rebuilding Roads(树形dp+背包转移)
- POJ-1947 Rebuilding Roads 树形DP+分组背包
- poj 1947 Rebuilding Roads (树形背包)
- POJ 1947 树形背包
- poj 1947 树形背包
- poj 1947 Rebuilding Roads 树形dp加背包
- Rebuilding Roads POJ - 1947 简单树形DP加背包问题
- POJ 1947 树形DP(分组背包)
- POJ-1947 Rebuilding Roads (树形DP+分组背包)
- poj 1947 树形背包 (删边)
- poj 1947 Rebuilding Roads 树形dp背包
- POJ 1947 经典树形背包
- POJ 1947 (树形DP+背包)
- poj 1947 Rebuilding Roads (树形背包dp)
- poj 1947(树形dp+背包问题)