zoukankan      html  css  js  c++  java
  • BZOJ3237: [Ahoi2013]连通图

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3237

    cdq分治+缩点。

    可以每次处理的时候把除l~r之外的边的端点都连起来。然后去跑cdq分治。

    当l==r的时候让那些修改边不连然后跑一边并查集。

    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #define rep(i,l,r) for (int i=l;i<=r;i++)
    #define down(i,l,r) for (int i=l;i>=r;i--)
    #define clr(x,y) memset(x,y,sizeof(x))
    #define maxn 200500
    using namespace std;
    struct data{int x,y,id,k,b;
    }a[21][maxn];
    int b[maxn][5];
    int fa[maxn],np[maxn],pos[maxn],n,m,Q;
    int read(){
        int x=0,f=1; char ch=getchar();
        while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();}
        while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    int find(int x){
        if (fa[x]==x) return x;
        return fa[x]=find(fa[x]);
    }
    void cdq(int dep,int l,int r,int n,int m){
        rep(i,1,m){
            data &c=a[dep][i],&c2=a[dep-1][i];
            c=(data){c2.x,c2.y,c2.id,0,0};
            pos[c2.id]=i;
        }
        if (l==r){
            rep(i,1,b[l][0]) a[dep][pos[b[l][i]]].b=1;
            rep(i,1,n) fa[i]=i;
            int cnt=0;
            rep(i,1,m) if (a[dep][i].b!=1) {
                data c=a[dep][i];
                int x=find(c.x),y=find(c.y);
                if (x!=y) fa[x]=y,cnt++;
            } 
            if (cnt==n-1) puts("Connected");
            else puts("Disconnected");    
            return;
        }
        rep(i,l,r) rep(j,1,b[i][0]) a[dep][pos[b[i][j]]].k=1;
        rep(i,1,n) fa[i]=i;
        rep(i,1,m) if (a[dep][i].k==0){
            data &c=a[dep][i];
            int x=find(c.x),y=find(c.y);
            if (x!=y) fa[x]=y;
        }   
        rep(i,1,n) np[i]=0;
        int nn=0,nm=0;
        rep(i,1,n) if (!np[find(i)]) np[find(i)]=++nn;
        rep(i,1,m) if (a[dep][i].k) {
            data c=a[dep][i];
            int x=find(c.x),y=find(c.y);
            a[dep][++nm]=(data){np[x],np[y],c.id,c.k,0};
        }
        int mid=(l+r)/2;
        cdq(dep+1,l,mid,nn,nm);
        cdq(dep+1,mid+1,r,nn,nm);
    }
    int main(){
        n=read(); m=read();
        int x,y;
        rep(i,1,m){
            x=read(); y=read();
            a[0][i]=(data){x,y,i,0,0};
        }
        Q=read();
        rep(i,1,Q){
            b[i][0]=read();
            rep(j,1,b[i][0]) b[i][j]=read();
        }
        cdq(1,1,Q,n,m);
        return 0;
    }
  • 相关阅读:
    js 数组去重求和 (转载)
    表格插件汇总(转载)
    SQL Server 用一张表的数据更新另一张表的数据(转载)
    C#创建DataTable(转载)
    C# DataTable 和List之间相互转换的方法(转载)
    维度表,实体表,事实表之间的关系
    Scala中foldLeft的总结
    Scala集合Map
    从合并两个Map说开去
    UDAF(用户自定义聚合函数)求众数
  • 原文地址:https://www.cnblogs.com/ctlchild/p/5053902.html
Copyright © 2011-2022 走看看