• 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;
    }
    
  • 相关阅读:
    maven 父子模块保持相同
    Maven deploy时排除指定的某个module
    源码,反码,补码
    Java日志之Slf4j,Log4J,logback原理总结
    Git Bash设置代理
    分享2个分布式锁
    二叉树的遍历记忆方法
    MySQL百万级数据分页查询及优化
    eclipse无法访问sun.misc.Unsafe类的解决办法
    Spring学习日志之纯Java配置的MVC框架搭建
  • 原文地址:https://www.cnblogs.com/xzz_233/p/9371068.html
Copyright © 2020-2023  润新知