zoukankan      html  css  js  c++  java
  • CF603E Pastoral Oddities

    CF603E Pastoral Oddities 

    度数不好处理。转化题意:不存在连通块为奇数时候就成功了(自底向上调整法证明)

    暴力:从小到大排序加入。并查集维护。全局变量记录奇数连通块的个数

    答案单调不增?

    类似整体二分。(其实类似决策单调性)

    横纵劈开,提前加入不会影响的边,复杂度得以保证

    按秩合并并查集撤销

    值域的访问,不用每次排序,答案一定是某个边的边权,提前排好序。直接访问即可

    #include<bits/stdc++.h>
    #define reg register int
    #define il inline
    #define numb (ch^'0')
    using namespace std;
    typedef long long ll;
    il void rd(int &x){
        char ch;x=0;bool fl=false;
        while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);
        (fl==true)&&(x=-x);
    }
    namespace Miracle{
    const int N=100000+5;
    const int M=300000+5;
    int n,m;
    struct node{
        int a,b,c;
        int id;
        bool friend operator <(node a,node b){
            return a.c<b.c;
        }
    }q[M],p[M];
    int fa[N],sz[N];
    struct po{
        int x,y,del;
        po(){}
        po(int xx,int yy,int dd){
            x=xx;y=yy;del=dd;
        }
    }sta[M];
    int top;
    int odd;
    int ans[M];
    int fin(int x){
        return fa[x]==x?x:fin(fa[x]);
    }
    void merge(int x,int y){
        x=fin(x),y=fin(y);
        if(x==y) return;
        if(sz[x]>sz[y]) swap(x,y);
        po now=po(x,y,0);
        if((sz[x]&1)&&(sz[y]&1)){
            now.del=2;
            odd-=2;
        }
        sta[++top]=now;
        fa[x]=y;
        sz[y]+=sz[x];
    }
    void dele(){
        po now=sta[top];
        odd+=now.del;
        sz[now.y]-=sz[now.x];
        fa[now.x]=now.x;
        --top;
    }
    void divi(int l,int r,int lo,int hi){
        if(l>r) return;
    //    cout<<" divi "<<l<<" "<<r<<" : "<<lo<<" "<<hi<<endl;
        int las=top;
        //cout<<" las "<<las<<endl;
        int mid=(l+r)>>1;
        int ans_mid=-1;
        for(reg i=l;i<=mid;++i){
            if(q[i].id<lo) merge(q[i].a,q[i].b);
        }
        for(reg i=lo;i<=hi;++i){
            if(p[i].id<=mid) merge(p[i].a,p[i].b);
            if(odd==0) {
                ans_mid=i;break;
            }
        }
        while(top!=las) dele();
        
        
        //cout<<mid<<" ans_mid "<<ans_mid<<endl;
        if(ans_mid==-1){
            for(reg i=l;i<=mid;++i) ans[i]=-1;
            for(reg i=l;i<=mid;++i){
                if(q[i].id<lo) merge(q[i].a,q[i].b);
            }
            divi(mid+1,r,lo,hi);
            while(top!=las) dele();
            return;
        }
        ans[mid]=p[ans_mid].c;
        
        for(reg i=lo;i<ans_mid;++i){
            if(p[i].id<l) merge(p[i].a,p[i].b);
        }
        divi(l,mid-1,ans_mid,hi);
        while(top!=las) dele();
        
        for(reg i=l;i<=mid;++i){
            if(q[i].id<lo) merge(q[i].a,q[i].b);
        }
        divi(mid+1,r,lo,ans_mid);
        while(top!=las) dele();
        
    }
    int main(){
        rd(n);rd(m);
        odd=n;
        if(n&1){
            for(reg i=1;i<=m;++i){
                puts("-1");
            }return 0;
        }
        for(reg i=1;i<=m;++i){
            rd(q[i].a);rd(q[i].b);rd(q[i].c);
            p[i]=q[i];p[i].id=i;
        }
        sort(p+1,p+m+1);
        for(reg i=1;i<=m;++i) q[p[i].id].id=i;
        for(reg i=1;i<=n;++i) fa[i]=i,sz[i]=1;
        divi(1,m,1,m);
        for(reg i=1;i<=m;++i){
            printf("%d
    ",ans[i]);
        }
        return 0;
    }    
    
    }
    signed main(){
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
       Date: 2019/3/5 19:27:14
    */

    从整体入手,发现答案不增。类似二分缩小范围。不会影响答案的边提前加上减少复杂度。

  • 相关阅读:
    TreeView checkbox
    学习wcf
    Python导入其他目录的模板
    xcode中如何设置编译后的app路径
    python中package机制的两种实现方式
    Page Object封装思想
    mac xcworkspace xcodebuild
    mac软件管理软件HomeBrew
    app被Rejected 的各种原因翻译
    scan-build static analyze help
  • 原文地址:https://www.cnblogs.com/Miracevin/p/10483649.html
Copyright © 2011-2022 走看看