zoukankan      html  css  js  c++  java
  • CodeChef

    https://www.codechef.com/problems/BLACKCOM

    题意:一颗5000个黑白结点的树,10W个查询寻找是否存在大小s并且有t和黑节点的子图

    一开始就觉得应当是一个树dp,但是总觉得怎么做怎么超时,用dp[5000][5000]预处理s大小t结点的可行性在时间复杂度上并不合理。

    但是这题有一个结论,对于树上一个大小为s的子图而言,如果同时有可以存在r个黑色节点和l个黑色节点,则l - r之间的所有黑色节点都可以构造。

    有了这个结论,就可以把dp方程转变为t结点的子树下大小为s最多的黑色和最少的黑色,然后取他们之间的值即可。

    细节在于子树之间的处理,dfs的时候同一颗子树是不能将子图加起来的,需要另开一个数组更新当前子树对答案的更新结果,最后统一赋值给最终答案。

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    inline int read(){int now=0;register char c=getchar();for(;!isdigit(c);c=getchar());
    for(;isdigit(c);now=now*10+c-'0',c=getchar());return now;}
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x);  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x);  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    typedef vector<int> VI;
    const double eps = 1e-9;
    const int maxn = 5e3 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,K;
    struct Edge{
        int to,next;
    }edge[maxn * 2];
    int head[maxn],tot;
    void init(){
        for(int i = 1; i <= N ; i ++) head[i] = -1;
        tot = 0;
    }
    void add(int u,int v){
        edge[tot].to = v;
        edge[tot].next = head[u];
        head[u] = tot++;
    }
    int color[maxn];
    int MAX[maxn][maxn],MIN[maxn][maxn];
    int oMAX[maxn][maxn],oMIN[maxn][maxn];
    int L[maxn],R[maxn],size[maxn];
    void dfs(int t,int la){
        MAX[t][1] = MIN[t][1] = color[t];
        size[t] = 1;
        for(int i = head[t]; ~i; i = edge[i].next){
            int v = edge[i].to;
            if(v == la) continue;
            dfs(v,t);
            for(int j = 1; j <= size[t] + size[v]; j ++){
                oMIN[t][j] = INF; oMAX[t][j] = 0;
            }
            for(int p = 0; p <= size[v]; p ++){
                for(int q = 1; q <= size[t]; q ++){
                    oMAX[t][p + q] = max(MAX[t][q] + MAX[v][p],oMAX[t][p + q]);
                    oMIN[t][p + q] = min(MIN[t][q] + MIN[v][p],oMIN[t][p + q]);
                }
            }
            size[t] += size[v];
            for(int p = 1; p <= size[t]; p ++){
                MAX[t][p] = oMAX[t][p];
                MIN[t][p] = oMIN[t][p];
            }
        }
        for(int i = 1; i <= size[t]; i ++){
            L[i] = min(L[i],MIN[t][i]);
            R[i] = max(R[i],MAX[t][i]);
        }
    } 
    int main(){
        int T; Sca(T);
        while(T--){
            Sca2(N,M);init();
            for(int i = 1; i <= N - 1; i ++){
                int u,v; Sca2(u,v);
                add(u,v); add(v,u);
            }
            for(int i = 1; i <= N ; i ++){
                L[i] = INF; R[i] = -INF;
            }
            for(int i = 1; i <= N ; i ++) Sca(color[i]);
            dfs(1,-1);
            for(int i = 1; i <= M ; i ++){
                int u,v; Sca2(u,v);
                if(L[u] <= v && v <= R[u]) puts("Yes");
                else puts("No");
            }
        }
        return 0;
    }
  • 相关阅读:
    HDU 1813 Escape from Tetris
    BZOJ 2276 Temperature
    BZOJ 4499 线性函数
    BZOJ 3131 淘金
    HDU 5738 Eureka
    POJ 2409 Let it Bead
    POJ 1286 Necklace of Beads
    POJ 1696 Space Ant
    Fox And Jumping
    Recover the String
  • 原文地址:https://www.cnblogs.com/Hugh-Locke/p/10280607.html
Copyright © 2011-2022 走看看