zoukankan      html  css  js  c++  java
  • bzoj4025: 二分图

    bzoj4025: 二分图


    博主回归啦,懒得开小号了

    神仙的一批。。。只会LCT,瑟瑟发抖

    首先用LCT维护一棵树,把边加和删的时间点拿出来sort一遍就变成了加边和删边操作

    如果要加进去一条边的时候发现这两点还没有联通就直接LCT上连边;要删的话如果在LCT上就在LCT上删边

    如果发现这条边会构成奇环(后面叫它“奇环边”)就不是二分图了,把这条边单独放在一个地方存起来(set),要删的时候从那里删

    每个时刻末尾,当没有奇环边的时候输出Yes,有就输出No

    然后发现很麻烦不好处理,因为从LCT上删边之后,一些奇环边就不再是奇环边了,可以重新回到LCT,但这个很不好维护,所以要保证在LCT上删边的时候没有一条奇环边对它有影响

    把边权设为这条边要删除的时间,维护最大生成树,每次要加新边的时候如果这两点已经联通就尝试消圈

    如果一条边加入会构成奇环,这条边又通过消圈进入了LCT,要把消掉的那条边加入奇环集合

    就能保证LCT上的边删除时奇环边集合不会对LCT有影响

    然后代码异常丑陋:

    #include<bits/stdc++.h>
    #define il inline
    #define vd void
    typedef long long ll;
    il int gi(){
        int x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    const int maxn=300100;
    struct edge{int u,v,t,ed,o,id;}E[400100];
    il bool operator <(const edge&a,const edge&b){
        if(a.t^b.t)return a.t<b.t;
        else return a.o==-1;
    }
    int ch[maxn][2],fa[maxn],siz[maxn],w[maxn],mn[maxn];bool rev[maxn];
    int A[maxn],B[maxn];
    il vd Rev(int x){if(x)std::swap(ch[x][0],ch[x][1]),rev[x]^=1;}
    il bool isrt(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
    il vd upd(int x){
        if(x){
            siz[x]=1+siz[ch[x][0]]+siz[ch[x][1]];
            mn[x]=x;
            if(w[mn[ch[x][0]]]<w[mn[x]])mn[x]=mn[ch[x][0]];
            if(w[mn[ch[x][1]]]<w[mn[x]])mn[x]=mn[ch[x][1]];
        }
    }
    il vd down(int x){
        if(x==0)return;
        if(!isrt(x))down(fa[x]);
        if(rev[x])Rev(ch[x][0]),Rev(ch[x][1]),rev[x]=0;
    }
    il vd rotate(int x){
        int y=fa[x],z=fa[y],o=x==ch[y][1];
        fa[x]=z;if(!isrt(y))ch[z][y==ch[z][1]]=x;
        ch[y][o]=ch[x][!o];fa[ch[x][!o]]=y;
        fa[y]=x;ch[x][!o]=y;
        upd(y);
    }
    il vd splay(int x){
        if(x==0)return;
        down(x);
        for(int y=fa[x],z=fa[y];!isrt(x);rotate(x),y=fa[x],z=fa[y])
            if(!isrt(y))rotate(((x==ch[y][0])!=(y==ch[z][0]))?x:y);
        upd(x);
    }
    il vd access(int x){for(int y=0;x;x=fa[y=x])splay(x),ch[x][1]=y,upd(x);}
    il vd makert(int x){access(x),splay(x),Rev(x);}
    il vd link(int x,int y){
        makert(x);fa[x]=y;
    }
    il vd cut(int x,int y){
        makert(x),access(y),splay(y);ch[y][0]=fa[x]=0;
    }
    il std::pair<int,int> dist(int x,int y){
        makert(x),access(y),splay(y);
        int z=y;while(ch[z][0])z=ch[z][0];
        if(z!=x)return std::make_pair(-1,-1);
        else return std::make_pair(siz[y]-1,mn[y]);
    }
    std::set<int>edgeList;
    bool yes[maxn];
    int main(){
        int n=gi(),m=gi(),T=gi(),cnt=0;
        for(int i=1;i<=m;++i){
            int u=gi(),v=gi(),st=gi()+1,ed=gi()+1;
            if(st==ed)continue;
            E[++cnt]=(edge){u,v,st,ed,1,i};
            E[++cnt]=(edge){u,v,ed,ed,-1,i};
        }
        std::stable_sort(E+1,E+cnt+1);
        int p=1;
        for(int i=0;i<=n;++i)w[i]=1e9;
        for(int t=1;t<=T;++t){
            while(p<=cnt&&E[p].t<=t){
                if(E[p].o==-1){
                    std::set<int>::iterator it=edgeList.find(E[p].id);
                    if(it!=edgeList.end())edgeList.erase(it);
                    else if(!yes[E[p].id])cut(E[p].u,n+E[p].id),cut(E[p].v,n+E[p].id);
                }else{
                    std::pair<int,int> d=dist(E[p].u,E[p].v);
                    if(E[p].u==E[p].v)edgeList.insert(E[p].id);
                    else if(d.first==-1){
                        int x=E[p].id+n;
                        w[x]=E[p].ed;
                        link(A[x]=E[p].u,x),link(B[x]=E[p].v,x);
                    }
                    else if(w[d.second]<E[p].ed){
                        int x=n+E[p].id;
                        w[x]=E[p].ed;
                        cut(d.second,A[d.second]),cut(d.second,B[d.second]);
                        if(d.first%4==2)yes[d.second-n]=1;
                        else edgeList.insert(d.second-n);
                        A[x]=E[p].u,B[x]=E[p].v;
                        link(x,A[x]),link(x,B[x]);
                    }
                    else if(d.first%4==0)edgeList.insert(E[p].id);
                    else yes[E[p].id]=1;
                }
                ++p;
            }
            if(edgeList.empty())puts("Yes");
            else puts("No");
        }
        return 0;
    }
    
  • 相关阅读:
    Infopath Notify 弹出提示信息
    window.showModalDialog 返回值
    【转】获得正文内容中的所有img标签的图片路径
    Json Datable Convert
    Sharepoint 列表 附件 小功能
    Surgey 权限更改
    SQL 触发器用于IP记录转换
    Caml语句 查询分配给当前用户及当前组
    jquery 1.3.2 auto referenced when new web application in VSTS2010(DEV10)
    TFS diff/merge configuration
  • 原文地址:https://www.cnblogs.com/xzz_233/p/9371068.html
Copyright © 2011-2022 走看看