zoukankan      html  css  js  c++  java
  • BZOJ_2208_[Jsoi2010]连通数_强连通分量+拓扑排序+手写bitset

    BZOJ_2208_[Jsoi2010]连通数_强连通分量+拓扑排序+手写bitset

    Description

    Input

    输入数据第一行是图顶点的数量,一个正整数N。 接下来N行,每行N个字符。第i行第j列的1表示顶点i到j有边,0则表示无边。

    Output

    输出一行一个整数,表示该图的连通数。

    Sample Input

    3
    010
    001
    100

    Sample Output

    9

    HINT

    对于100%的数据,N不超过2000。


    直接缩点+拓扑排序统计答案即可。

    每步转移是O(n)的,可以用bitset优化到O(n/32)。

    其实就是想练习一下手写bitset,显然没有STL的块。

    总时间复杂度O(nnm/32)

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 2050
    #define M 4000500
    #define _min(x,y) ((x)<(y)?(x):(y))
    typedef unsigned int ut;
    const int M1=65535;
    inline char nc() {
        static char buf[100000],*p1,*p2;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    int rc() {
        char s=nc();
        while(s<'0'||s>'1') s=nc();
        return s=='1';
    }
    int rd() {
        int x=0; char s=nc();
        while(s<'0'||s>'9') s=nc();
        while(s>='0'&&s<='9') x=(x<<3)+(x<<1)+s-'0',s=nc();
        return x;
    }
    int n,block,h[1<<16];
    int g1(unsigned int x) {
        return h[x>>16]+h[x&M1];
    }
    struct Bitset {
        ut b[70];
        int get_num() {
            int i,re=0;
            for(i=1;i<=block;i++) re+=g1(b[i]);
            return re;
        }
        Bitset operator | (const Bitset &x) const {
            Bitset re; int i;
            for(i=1;i<=block;i++) re.b[i]=(b[i]|x.b[i]);
            return re;
        }
    }f1[N],f2[N];
    int head[N],to[M],nxt[M],in[N],Q[N],l,r;
    int S[N],bel[N],siz[N],L[80],R[80],pos1[N],pos2[N],dfn[N],low[N],tot,scc,top,ins[N],xx[M],yy[M],qwq,cnt;
    inline void add(int u,int v) {
        to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
    }
    void dfs(int x) {
        int i;
        dfn[x]=low[x]=++tot; S[++top]=x; ins[x]=1;
        for(i=head[x];i;i=nxt[i]) {
            if(!dfn[to[i]]) {
                dfs(to[i]);
                low[x]=_min(low[x],low[to[i]]);
            }else if(ins[to[i]]) {
                low[x]=_min(low[x],dfn[to[i]]);
            }
        }
        if(dfn[x]==low[x]) {
            int t=S[top--]; ins[t]=0;
            bel[t]=++scc; f2[scc]=f1[t];
            siz[scc]=1;
            while(t!=x) {
                t=S[top--]; ins[t]=0;
                bel[t]=scc; f2[scc]=f2[scc]|f1[t];
                siz[scc]++;
            }
        }
    }
    int main() {
        n=rd();
        register int i,j;
        int x;
        for(i=1;i<=M1;i++) h[i]=h[i>>1]+(i&1);
        block=n/32;
        for(i=1;i<=block;i++) {
            L[i]=R[i-1]+1; R[i]=i*32;
            for(j=L[i];j<=R[i];j++) {
                pos1[j]=i; pos2[j]=j-L[i];
            }
        }
        if(R[block]!=n) {
            L[block+1]=R[block]+1; R[++block]=n;
            for(i=L[block];i<=n;i++) pos1[i]=block,pos2[i]=i-L[block];
        }
        for(i=1;i<=n;i++) {
            for(j=1;j<=n;j++) {
                x=rc();
                if(x) f1[i].b[pos1[j]]|=(1<<pos2[j]),add(i,j),xx[++qwq]=j,yy[qwq]=i;
            }
            f1[i].b[pos1[i]]|=(1<<pos2[i]);
        }
        for(i=1;i<=n;i++) {
            if(!dfn[i]) dfs(i);
        }
        memset(head,0,sizeof(head)); cnt=0;
        for(i=1;i<=qwq;i++) {
            if(bel[xx[i]]!=bel[yy[i]]) {
                add(bel[xx[i]],bel[yy[i]]); in[bel[yy[i]]]++;
            }
        }
        for(i=1;i<=scc;i++) {
            if(!in[i]) Q[r++]=i;
        }
        int ans=0;
        while(l<r) {
            x=Q[l++]; ans+=siz[x]*f2[x].get_num();
            for(i=head[x];i;i=nxt[i]) {
                in[to[i]]--;
                f2[to[i]]=f2[to[i]]|f2[x];
                if(in[to[i]]==0) Q[r++]=to[i];
            }
        }
        printf("%d
    ",ans);
    }
    
    
  • 相关阅读:
    vm virtualBox下 centos7 Linux系统 与本地 window 系统 网络连接 配置
    ArrayList的扩容机制
    如何在Anaconda中实现多版本python共存
    安装selenium和chromedriver
    python中安装pandas
    C#解析数组形式的json数据
    angular学习总结
    echarts实现环形图
    echarts实现折线图
    angular安装记录
  • 原文地址:https://www.cnblogs.com/suika/p/9237793.html
Copyright © 2011-2022 走看看