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;
    }
    
  • 相关阅读:
    jQuery Validate 插件
    本地存储 web storage
    ajax简介及JS写原生ajax
    swiper插件简介及用法
    JavaScript中的string对象及方法
    javascript数组中的方法
    面向对象
    logging模块具体补充
    模块补充
    内置函数总结
  • 原文地址:https://www.cnblogs.com/asuldb/p/10523267.html
Copyright © 2011-2022 走看看