zoukankan      html  css  js  c++  java
  • 「bzoj 4025: 二分图」

    题目

    显然二分图没有奇环

    于是考虑使用并查集维护一下看看是否存在奇环

    我们可以考虑加权并查集,维护出(x)(fa_x)的实际距离

    由于我们只需要考虑奇偶性,于是我们处理出到根的路径异或一下就好了

    之后是动态删边的问题,我们可以考虑线段树分治

    于是我们需要在线段树分治的时候维护一个并查集,还需要支持撤回操作

    我们只需要一个不路径压缩的启发式合并并查集就好了

    代码

    #include<cstdio>
    #include<vector>
    #define re register
    inline int read() {
        char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
        while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
    }
    std::vector<int> u[320005],v[320005],f[320005],st[320005];
    int n,m,T,now,tp;
    int ans[100005],fa[100005],h[100005],dis[100005];
    void change(int l,int r,int x,int y,int i,int a,int b) {
        if(x<=l&&y>=r) {u[i].push_back(a),v[i].push_back(b);return;}
        int mid=l+r>>1;
        if(x<=mid) change(l,mid,x,y,i<<1,a,b);
        if(y>=mid+1) change(mid+1,r,x,y,i<<1|1,a,b);
    }
    inline int find(int x,int opt) {
        if(!opt) now=0;
        while(fa[x]!=x) now^=dis[x],x=fa[x];
        return x;
    }
    inline int merge(int x,int y) {
        tp=0;
        if(h[x]<h[y]) {dis[x]=(now^1);fa[x]=y;return x;}
        if(h[y]<h[x]) {dis[y]=(now^1);fa[y]=x;return y;}
        h[x]++;fa[y]=x;tp=1;dis[y]=(now^1);return y;
    }
    inline void clear(int i) {
        for(re int j=st[i].size()-1;~j;--j) {
            int x=st[i][j];
            h[fa[x]]-=f[i][j];fa[x]=x;
        }
    }
    void solve(int l,int r,int i) {
        for(re int j=0;j<u[i].size();j++) {
            int xx=find(u[i][j],0),yy=find(v[i][j],1);
            if(xx!=yy) st[i].push_back(merge(xx,yy)),f[i].push_back(tp);
            else if(!now) {
                for(re int k=l;k<=r;k++) ans[k]=1;
                clear(i);return;
            }
        }
        if(l==r) {clear(i);return;}
        int mid=l+r>>1;
        solve(mid+1,r,i<<1|1);solve(l,mid,i<<1);
        clear(i);
    }
    int main() {
        n=read(),m=read(),T=read();
        for(re int i=1;i<=n;i++) fa[i]=i,h[i]=1;
        for(re int x,y,s,t,i=1;i<=m;i++) {
            x=read(),y=read(),s=read()+1,t=read();
            if(s>t) continue;
            change(1,T,s,t,1,x,y);
        }
        solve(1,T,1);
        for(re int i=1;i<=T;i++) puts(ans[i]?"No":"Yes");
        return 0;
    }
    
  • 相关阅读:
    CodeForces gym Nasta Rabbara lct
    bzoj 4025 二分图 lct
    CodeForces 785E Anton and Permutation
    bzoj 3669 魔法森林
    模板汇总——快读 fread
    bzoj2049 Cave 洞穴勘测 lct
    bzoj 2002 弹飞绵羊 lct裸题
    HDU 6394 Tree 分块 || lct
    HDU 6364 Ringland
    nyoj221_Tree_subsequent_traversal
  • 原文地址:https://www.cnblogs.com/asuldb/p/10523267.html
Copyright © 2011-2022 走看看