bzoj 2208: [Jsoi2010]连通数

来源:互联网 发布:直播狗网络电视官网 编辑:程序博客网 时间:2024/05/16 04:55

神奇bitset;

#include<bits/stdc++.h>#define rep(i,k,n) for(int i=k;i<=(n);i++)using namespace std;const int N = 2005;const int M = 4000000;struct E {    int to, next;    E(int to = 0, int next = 0): to(to), next(next) {}} edge[2][M];int head[2][N], tot[2], n;void add(int x, int y, int op) {    edge[op][++tot[op]] = E(y, head[op][x]);    head[op][x] = tot[op];}int pre[N], scc[N], scc_cnt = 0, fa[N], lw[N], clk = 0, sta[N], top = 0, num[N], vis[N];void dfs(int x) {    pre[x] = lw[x] = ++clk;    sta[++top] = x;    for(int i = head[0][x]; i; i = edge[0][i].next)if(!scc[edge[0][i].to]) {            int v = edge[0][i].to;            if(!pre[v]) {                dfs(v);                lw[x] = min(lw[x], lw[v]);            } else if(pre[v] < lw[x])lw[x] = pre[v];        }    if(lw[x] == pre[x]) {        scc_cnt++;        while(top) {            scc[sta[top]] = scc_cnt;            num[scc_cnt]++;            if(sta[top--] == x)break;        }    }}void dfs2(int x) {    vis[x] = 1;    for(int i = head[1][x]; i; i = edge[1][i].next) {        int v = edge[1][i].to;        if(!vis[v])            dfs2(v);    }    sta[top--] = x;}bitset<N> t[N];int main() {//    freopen("in.in", "r", stdin);//    freopen("out.out","w",stdout);    scanf("%d", &n);    char s[N];    tot[0] = tot[1] = 0;    rep(i, 1, n) {        scanf("%s", s + 1);        rep(j, 1, n)if(s[j] == '1')add(i, j, 0);    }    rep(i, 1, n)    if(!pre[i])    dfs(i);    rep(x, 1, n){t[scc[x]][x] = 1;    for(int i = head[0][x]; i; i = edge[0][i].next) {        int v = edge[0][i].to;        if(scc[x] != scc[v])add(scc[x], scc[v], 1);    }    }    top = scc_cnt;    rep(i, 1, scc_cnt)if(!vis[i])        dfs2(i);    int ans = 0;//rep(x,1,n){printf("%d\n",x);rep(i,0,n+1)printf("%d",t[x][i] ? 1 : 0);printf("\n");}    for(int x = scc_cnt; x; x--) {        for(int i = head[1][sta[x]]; i; i = edge[1][i].next) {            int v = edge[1][i].to;            t[sta[x]] =t[sta[x]] | t[v];        }//printf("%d\n",sta[x]);rep(i,1,n)printf("%d",t[sta[x]][i] ? 1 : 0);printf("\n");        ans += num[sta[x]] * t[sta[x]].count();    }    printf("%d", ans);    return 0;}
0 0
原创粉丝点击