poj 1947 树形DP
2014-08-09 19:22
393 查看
一开始没有想到思路,哎,还是太弱啊。看了别人的思路,知道是树形DP。
设d[i][j]为以i为根节点孤立出节点为j的子树至少需要砍得次数(注意:这个子树是包括根节点i的)。
接下来再说说怎么得到状态转移方程:
(1)当j为1的话,d[i][1]=节点i孩子的个数;
(2)若以i的孩子son[i]为根的子树不在以i为根节点孤立出节点数为j的子树的内部,则有没有以son[i]为根的子树无所谓;
若以son[i]为根节点的子树有k个节点在以i为根孤立出节点数为j的子树中则 整个树分成两部分,此时,d[i][j]=d[i][j-k]+d[son[i]][k]-1;
之所以减一是因为初始化的时候(d[i][1]=节点i孩子的个数)已经把这个孩子排除在外了(即已经砍了一刀),现在要加进来,所以要修复这条边(即减少一刀);
代码如下:
设d[i][j]为以i为根节点孤立出节点为j的子树至少需要砍得次数(注意:这个子树是包括根节点i的)。
接下来再说说怎么得到状态转移方程:
(1)当j为1的话,d[i][1]=节点i孩子的个数;
(2)若以i的孩子son[i]为根的子树不在以i为根节点孤立出节点数为j的子树的内部,则有没有以son[i]为根的子树无所谓;
若以son[i]为根节点的子树有k个节点在以i为根孤立出节点数为j的子树中则 整个树分成两部分,此时,d[i][j]=d[i][j-k]+d[son[i]][k]-1;
之所以减一是因为初始化的时候(d[i][1]=节点i孩子的个数)已经把这个孩子排除在外了(即已经砍了一刀),现在要加进来,所以要修复这条边(即减少一刀);
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAX 155 #define INF 0x3f3f3f3f int dp[MAX][MAX]; int N,P,ans=0; int fa,son,root=1; int tree[MAX][MAX]; bool father[MAX]; void DP(int r) { int i,j,k; dp[r][1]=tree[r][0]; //初始化 if(tree[r][0]==0) return ; for(k=1;k<=tree[r][0];k++){ int s=tree[r][k]; DP(s); for(i=P;i>=1;i--) { for(j=1;j<i;j++) { dp[r][i]=min(dp[r][i],dp[s][j]+dp[r][i-j]-1); //状态转移 } } } } int main() { int i,j; scanf("%d%d",&N,&P); memset(tree,0,sizeof(tree)); for(i=0;i<N-1;i++) { scanf("%d%d",&fa,&son); tree[fa][++tree[fa][0]]=son; father[son]=1; } memset(dp,0x3f,sizeof(dp)); for(i=1;i<=N;i++) { if(!father[i]) { root=i;break; } } DP(root); ans=dp[root][P]; for(i=1;i<=N;i++) { ans=min(ans,dp[i][P]+1); //除了根节点,其他节点要想成为独立的根,必先与父节点断绝关系,所以要先加1 } printf("%d\n",ans); return 0; }
相关文章推荐
- 【树形DP】【多叉转二叉】【poj 1947】Rebuilding Roads
- Rebuilding Roads - POJ 1947 树形dp
- poj 1947 Rebuilding Roads 树形dp背包
- poj 1947 Rebuilding Roads(树形dp)
- POJ 1947 树形DP(分组背包)
- poj 1947 Rebuilding Roads ---树形DP
- poj 1947(树形dp)
- poj 1947(树形dp)
- POJ 1947 树形DP
- poj 1947 树形dp(得到含P个节点联通块的最小切边数)
- POJ--1947--Rebuilding Roads--树形DP
- 树形dp(poj 1947 Rebuilding Roads )
- Rebuilding Roads POJ - 1947 简单树形DP加背包问题
- POJ 1947 Rebuilding Roads(树形DP)
- POJ 1947 Rebuilding Roads 树形DP
- poj 1947 Rebuilding Roads 【树形DP】 【求至少删去树中 多少条边 使得树中节点数为P】
- POJ题目1947 Rebuilding Roads(树形dp)
- POJ 1947 Rebuilding Roads - 树形DP
- POJ_1947 Rebuilding Roads --树形DP
- poj 1947 Rebuilding Roads(树形dp)