Bichrome Tree (树形dp)

6611: Bichrome Tree

时间限制: 1 Sec  内存限制: 128 MB
提交: 154  解决: 41
[提交] [状态] [讨论版] [命题人:admin]

题目描述

We have a tree with N vertices. Vertex 1 is the root of the tree, and the parent of Vertex i (2≤i≤N) is Vertex Pi.
To each vertex in the tree, Snuke will allocate a color, either black or white, and a non-negative integer weight.
Snuke has a favorite integer sequence, X1,X2,…,XN, so he wants to allocate colors and weights so that the following condition is satisfied for all v.
The total weight of the vertices with the same color as v among the vertices contained in the subtree whose root is v, is Xv.
Here, the subtree whose root is v is the tree consisting of Vertex v and all of its descendants.
Determine whether it is possible to allocate colors and weights in this way.

Constraints
1≤N≤1 000
1≤Pi≤i−1
0≤Xi≤5 000

输入

Input is given from Standard Input in the following format:
N
P2 P3 … PN
X1 X2 … XN

输出

If it is possible to allocate colors and weights to the vertices so that the condition is satisfied, print POSSIBLE; otherwise, print IMPOSSIBLE.

样例输入

扫描二维码关注公众号,回复: 2536954 查看本文章
3
1 1
4 3 2

样例输出

POSSIBLE

提示

For example, the following allocation satisfies the condition:
Set the color of Vertex 1 to white and its weight to 2.
Set the color of Vertex 2 to black and its weight to 3.
Set the color of Vertex 3 to white and its weight to 2.
There are also other possible allocations.

题目:给一棵树每个点分配一个权值和颜色,只有黑和白两种颜色,再给一个序列X,问对于一个节点u,u和他子树中颜色相同节点的权值和正好等于Xu。

分析:不用管这个节点的颜色与权值,只关心它和它的子树之间的颜色和权值关系即可。以当前节点为黑色举例,那么它的子树中黑色节点权值之和就是Xv,设f[v]为v子树中与v节点颜色相反的节点权值之和,前面假设v为黑色了,那么f[v]则代表v子树中白色节点权值之和。我们要使得f[v]尽量小,那么对于以后的祖先节点为白色的才有可能不大于Xi,小与Xi没关系,我们可以用i节点权值大使得正好等于Xi。

仍然假设u为黑色。讨论它的子树v。

若u,v同色那么,v的权值和即Xv要计算入u中看是否超过Xu。

若u,v不同色,f[v]的值要计算入u中看是否超过Xu。

u与v同色,把Xv装进u结点, dp[j] = min( dp[j-X[v]]+f[v] );

u与不同色,把f[v]装进u结点,dp[j] = min( dp[j-f[v]]+X[v] );

#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string.h>
#include<vector>
#include<stdlib.h>
#include<math.h>
#include<queue>
#include<deque>
#include<ctype.h>
#include<map>
#include<set>
#include<stack>
#include<string>
#define INF 0x3f3f3f3f
#define FAST_IO ios::sync_with_stdio(false)
const double PI = acos(-1.0);
const double eps = 1e-6;
const int MAX=1e5+10;
const int mod=1e9+7;
typedef long long ll;
using namespace std;
#define gcd(a,b) __gcd(a,b)
inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
inline ll qpow(ll a,ll b){ll r=1,t=a; while(b){if(b&1)r=(r*t)%mod;b>>=1;t=(t*t)%mod;}return r;}
inline ll inv1(ll b){return qpow(b,mod-2);}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll r=exgcd(b,a%b,y,x);y-=(a/b)*x;return r;}
inline ll read(){ll x=0,f=1;char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;for(;isdigit(c);c=getchar()) x=x*10+c-'0';return x*f;}
//freopen( "in.txt" , "r" , stdin );
//freopen( "data.txt" , "w" , stdout );
struct node
{
    int to,next;
}e[MAX];
int head[MAX],cut;
void add(int u,int v)
{
    e[cut].to=v;
    e[cut].next=head[u];
    head[u]=cut++;
}
int f[MAX],dp[MAX],p[MAX],x[MAX],n;
int dfs(int u)
{
    for(int i=head[u];~i;i=e[i].next)//先遍历。
        dfs(e[i].to);
    memset(dp,0x3f,sizeof(dp));
    dp[0]=0;
    for(int i=head[u];~i;i=e[i].next)
    {
        int v=e[i].to;
        for(int j=x[u];j>=0;j--)
        {
            int temp=INF;
            if(j>=x[v]) //u,v同色。
                temp=min(temp,dp[j-x[v]]+f[v]);
            if(j>=f[v])//u,v不同色。
                temp=min(temp,dp[j-f[v]]+x[v]);
            dp[j]=temp;
        }
    }
    for(int i=0;i<=x[u];i++)
        f[u]=min(f[u],dp[i]);
}
int main()
{
    cut=0;
    memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for(int i=2;i<=n;i++)
    {
        scanf("%d",&p[i]);
        add(p[i],i);
    }
    for(int i=1;i<=n;i++)
        scanf("%d",&x[i]);
    memset(f,0x3f,sizeof(f));
    
    dfs(1);
    if(f[1]<INF)
        printf("POSSIBLE\n");
    else
        printf("IMPOSSIBLE\n");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ToBeYours/article/details/81351942