zoukankan      html  css  js  c++  java
  • uoj #14.【UER #1】DZY Loves Graph

    http://uoj.ac/problem/14

    由于加入的边权递增,可以直接运行kruskal并支持撤销,但这样如果反复批量删边和撤销,时间复杂度会退化,因此需要对删边操作加上延时处理,只有在删边后下一个操作不是撤销时才执行删边。由于有撤销,并查集需要按秩合并且不路径压缩。

    #include<bits/stdc++.h>
    typedef long long i64;
    const int N=500007;
    int _(){
        int x;
        scanf("%d",&x);
        return x;
    }
    int n,m;
    int f[N][2];
    int po,ep=0,ep1=0;
    #define sz f][1
    #define fa f][0
    int gf(int x){
        while(x!=x[fa])x=x[fa];
        return x;
    }
    void lk(int x,int y){
        x[fa]=y;
        y[sz]+=x[sz];
    }
    void ct(int x,int y){
        x[fa]=x;
        y[sz]-=x[sz];
    }
    struct ev{
        int a,b,ec;
        i64 sum;
        void undo(){ct(a,b);}
    }e[N];
    void fix(){
        while(ep1<ep)e[ep--].undo();
    }
    void ae(int v){
        po=0;
        fix();
        ev&e0=e[ep];
        ev&e1=e[ep1=++ep];
        int x=gf(_()),y=gf(_());
        if(x==y){
            e1=(ev){0,0,e0.ec,e0.sum};
        }else{
            if(x[sz]>y[sz])std::swap(x,y);
            lk(x,y);
            e1=(ev){x,y,e0.ec+1,e0.sum+v};
        }
    }
    void de(){
        po=1;
        fix();
        ep1=ep-_();
    }
    void undo(){
        if(!po)e[ep--].undo();
        ep1=ep;
    }
    int main(){
        n=_();m=_();
        for(int i=1;i<=n;++i){
            i[fa]=i;
            i[sz]=1;
        }
        for(int i=1,o;i<=m;++i){
            o=_();
            if(o==2272)ae(i);
            else if(o==2596033)de();
            else undo();
            printf("%lld",e[ep1].ec==n-1?e[ep1].sum:0);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    HDU 1429
    HDU 1622
    HDU 3335
    HDU 4160
    HDU 1350
    HDU 5086
    HDU 1300
    HDU 3047
    HDU 3038
    HDU 5100
  • 原文地址:https://www.cnblogs.com/ccz181078/p/7374280.html
Copyright © 2011-2022 走看看