zoukankan      html  css  js  c++  java
  • 染色(dye)

    染色(dye)

    Description

    Serene 和 Achen 在玩染色游戏。Serene 和 Achen 站在一个 n 个点 m 条边的无向连通图中,在第 i 次玩染色游戏时,Serene 在 a_i,Achen 在 b_i,并且所有节点都变为白色,在这次游戏中,Serene 和 Achen 会走过一些边,并且把路途中经过的所有点染成黑色,她们一共需要把 k_i 个点染成黑色(一个点如 果被染多次只计算一次)。

    但是 Serene 和 Achen 不想太累,她们的劳累值是她们俩所经过的所有的边的最 大编号。Serene 想知道,每次玩染色游戏时 Serene 和 Achen 的最小的劳累值。

    Input

    一行两个整数 n,m

    接下来 m 行每行两个数 x_i,y_i 表示编号为 i 的边所连接的两个点

    接下来一行一个数 q,表示 Serene 和 Achen 做游戏的次数

    接下来 q 行每行两个数 a_i,b_i,k_i 表示 Serene 和 Achen 的初始位置和需要染成黑色的点数

    Output

    q 行,对于每次游戏输出最小劳累值。

    Sample Input

    5 6

    2 3

    4 5

    1 2

    1 3

    1 4

    1 5

    6

    2 4 3

    2 4 4

    2 4 5

    1 3 3

    1 3 4

    1 3 5

    Sample Output

    1

    2

    3

    1

    5

    5

    Hint

    对于 20%的数据,n,m,q<=500

    对于 60%的数据,n,m,q<=50000

    对于 100%的数据,n,m,q<=200000

    原题

    整体二分。

    二分的一个答案显然可以用并查集维护。

    若是每次暴力从头建并查集肯定会死亡TLE。

    于是用按秩合并的并查集,每次二分之后先往又区间走,往右走之后操作是往并查集里加。

    走完不得不往左走时,把之前操作的后一半撤销。为了撤销强行开了个栈存操作。

    然后奥妙地跑得比std快。

    正解是整体二分时不按dfs序做而是按bfs序做。

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<vector>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    const int N=400007;
    #define For(i,a,b) for(int i=(a);i<=(b);i++)
    #define Rep(i,a,b) for(int i=(a);i>=(b);i--)
    typedef long long LL;
    using namespace std;
    int n,m,q,fa[N],sz[N],ans[N];
    
    template<typename T>void read(T &x)  {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    struct edge {
        int u,v,w;
    }e[N];
    
    struct node {
        int x,y,k,id;
    }qs[N],tp[N];
    
    int find(int x) { return x==fa[x]?x:find(fa[x]); }
    
    struct op {
        int x,fa,id;
        op(){}
        op(int x,int fa,int id):x(x),fa(fa),id(id){}
    }sta[N*18];
    int top;
    void solve(int l,int r,int ql,int qr,int f) {
        if(l>r||ql>qr) return ;
        if(l==r) {
            For(i,ql,qr) ans[qs[i].id]=l;
            return;
        }
        int mid=((l+r)>>1);
        int ll=ql-1,rr=qr+1;
        if(f) {
            For(i,l,mid) {
                int x=find(e[i].u),y=find(e[i].v);
                if(x!=y) {
                    if(sz[x]<=sz[y]) {
                        fa[x]=y,sz[y]+=sz[x];
                        sta[++top]=op(x,y,i);
                    }
                    else  {
                        fa[y]=x,sz[x]+=sz[y];
                        sta[++top]=op(y,x,i);
                    }
                }
            }
        }
        For(i,ql,qr) {
            int x=find(qs[i].x),y=find(qs[i].y);
            if((x==y&&sz[x]>=qs[i].k)||(x!=y&&sz[x]+sz[y]>=qs[i].k)) tp[++ll]=qs[i];
            else tp[--rr]=qs[i];
        }
        For(i,ql,qr) qs[i]=tp[i];
        solve(mid+1,r,rr,qr,1);
        Rep(i,top,1) {
            if(sta[i].id<=((l+mid)>>1)) break;
            int x=sta[i].x,f=sta[i].fa;
            fa[x]=x; sz[f]-=sz[x]; top--;
        }
        solve(l,mid,ql,ll,0);
    }
    
    #define DEBUG
    int main() {
    #ifdef DEBUG
        freopen("dye.in","r",stdin);
        freopen("dye.out","w",stdout);
    #endif
        read(n); read(m);
        For(i,1,m) {
            read(e[i].u); read(e[i].v); 
            e[i].w=i;
        }
        read(q);
        For(i,1,q) {
            read(qs[i].x); read(qs[i].y);
            read(qs[i].k); qs[i].id=i;
        }
        For(i,1,n) fa[i]=i,sz[i]=1;
        solve(1,m,1,q,1);
        For(i,1,q) printf("%d
    ",ans[i]);
        return 0;
    }
    /*
    5 6
    2 3
    4 5
    1 2
    1 3
    1 4
    1 5
    6
    2 4 3
    2 4 4
    2 4 5
    1 3 3
    1 3 4
    1 3 5
    */
    View Code

     

  • 相关阅读:
    【Language】 TIOBE Programming Community Index for February 2013
    【diary】good health, good code
    【web】a little bug of cnblog
    【Git】git bush 常用命令
    【web】Baidu zone ,let the world know you
    【diary】help others ,help yourself ,coding is happiness
    【Git】Chinese messy code in widows git log
    【windows】add some font into computer
    SqlServer启动参数配置
    关于sqlserver中xml数据的操作
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8570152.html
Copyright © 2011-2022 走看看