zoukankan      html  css  js  c++  java
  • [BZOJ5072] 小A的树

    设计状态(f[i][j])表示以i为根的子树,包含j个点的最小黑点数,(g[i][j])表示以(i)
    为子树,包含(j)个点的最大黑点数,然后树形背包转移即可。
    每次询问的时候就看包含x在不在(f[0][y])(g[0][y])之间。
    因为一个子图每删除一个点,再加入一个点,黑点个数的变化量不超过(1),所以一定有策略可以达到([min,max])中的每一个值.

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int N=5005;
    int f[N][N],T,g[N][N],head[N],ecnt,col[N],siz[N],n;
    struct Edge{int to,nxt;}e[N<<1];
    inline void add(int bg,int ed) {e[++ecnt]=(Edge){ed,head[bg]};head[bg]=ecnt;}
    inline void ins(int x,int y) {add(x,y);add(y,x);}
    void dfs(int x,int fa) {
    	f[x][1]=g[x][1]=col[x];siz[x]=1;
    	for(int i=head[x];i;i=e[i].nxt) {
    		int v=e[i].to;
    		if(v!=fa) dfs(v,x);
    		else continue;
    		for(int j=siz[x];j;j--) {
    			for(int k=siz[v];k;k--) {
    				f[x][j+k]=min(f[x][j+k],f[x][j]+f[v][k]);
    				g[x][j+k]=max(g[x][j+k],g[x][j]+g[v][k]);
    			}
    		}
    		siz[x]+=siz[v];
    	}
    	for(int i=1;i<=n;i++) f[0][i]=min(f[0][i],f[x][i]),g[0][i]=max(g[0][i],g[x][i]);
    }
    int main() {
    	scanf("%d",&T);
    	while(T--) {
    		memset(f,0x3f,sizeof f);
    		memset(g,0xcf,sizeof g);
    		int q,x,y;
    		scanf("%d%d",&n,&q);
    		ecnt=0;memset(head,0,sizeof head);
    		for(int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),ins(x,y);
    		for(int i=1;i<=n;i++) scanf("%d",&col[i]);
    		dfs(1,0);
    		while(q--) {
    			scanf("%d%d",&y,&x);
    			if(f[0][y]<=x&&x<=g[0][y]) puts("YES");
    			else puts("NO");
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    C++ SOCKET 基础编程
    Linux 基础
    Python 基础
    H5禁止微信内置浏览器调整字体大小
    css中 出现height为100%失效的原因及解决方案
    CSS3 clip-path 用法介绍
    Web的26项基本概念和技术
    Web前端年后跳槽面试复习指南
    基于 HTML5 Canvas 的交互式地铁线路图
    常用长度单位PX/EM/PT/百分比转换公式与对照表
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9819254.html
Copyright © 2011-2022 走看看