• AtCoder Regular Contest 083 E


    题目传送门:https://arc083.contest.atcoder.jp/tasks/arc083_c

    题目大意:

    给定一棵树,你可以给这些点任意黑白染色,并且赋上权值,现给定一个序列(X_i),满足对于每一个点(i),整棵子树内所有和(i)颜色相同的点的权值和为(X_i),问是否可能


    首先因为权值大小任意,所以(v)的子树内权值和只要不超过(X_v)就好,那么对于一个点(v)假定其为黑色,那么子树中黑色总和为(X_v),白色总和就要尽量小,定义为(f_v)

    那么选定(v)为黑色后,假定子树内黑色总和为(B),白色总和为(W),那么对于每个子节点(v)有两种选择

    (B+=X_u,W+=f_u)(B+=f_u,W+=X_u)

    /*program from Wolfycz*/
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x3f3f3f3f
    #define min(x,y) (x<y?x:y)
    #define max(x,y) (x>y?x:y)
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline char gc(){
    	static char buf[1000000],*p1=buf,*p2=buf;
    	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int frd(){
    	int x=0,f=1; char ch=gc();
    	for (;ch<'0'||ch>'9';ch=gc())	if (ch=='-')	f=-1;
    	for (;ch>='0'&&ch<='9';ch=gc())	x=(x<<3)+(x<<1)+ch-'0';
    	return x*f;
    }
    inline int read(){
    	int x=0,f=1; char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')	f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<3)+(x<<1)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x<0)	putchar('-'),x=-x;
    	if (x>9)	print(x/10);
    	putchar(x%10+'0');
    }
    const int N=1e3,M=5e3;
    int pre[N+10],now[N+10],child[N+10],tot;
    int f[N+10],g[2][M+10],v[N+10];
    void join(int x,int y){pre[++tot]=now[x],now[x]=tot,child[tot]=y;}
    void dfs(int x){
    	for (int p=now[x],son=child[p];p;p=pre[p],son=child[p])	dfs(son);
    	memset(g[0],63,sizeof(g[0]));
    	int T=0; g[T][0]=0;
    	for (int p=now[x],son=child[p];p;p=pre[p],son=child[p]){
    		T^=1;
    		memset(g[T],63,sizeof(g[T]));
    		for (int i=0;i<=v[x];i++){
    			if (i>=v[son])	g[T][i]=min(g[T][i],g[T^1][i-v[son]]+f[son]);
    			if (i>=f[son])	g[T][i]=min(g[T][i],g[T^1][i-f[son]]+v[son]);
    		}
    	}
    	for (int i=0;i<=v[x];i++)	f[x]=min(f[x],g[T][i]);
    }
    int main(){
    	int n=read();
    	for (int i=2;i<=n;i++)	join(read(),i);
    	for (int i=1;i<=n;i++)	v[i]=read();
    	memset(f,63,sizeof(f));
    	dfs(1);
    	printf(f[1]<inf?"POSSIBLE
    ":"IMPOSSIBLE
    ");
    	return 0;
    }
    
  • 相关阅读:
    html 上传图片前预览
    php获取当月天数及当月第一天及最后一天、上月第一天及最后一天实现方法
    php 计算 pdf文件页数
    php 获取半年内每个月的订单数量, 总价, 月份
    php 获取两个数组之间不同的值
    小程序支付功能
    关于nginx的Job for nginx.service failed because the control process exited with error code.错误
    linux 安装 Apollo
    MongoDB待续。。。
    ABP vNext...待续
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/10072079.html
Copyright © 2020-2023  润新知