• BZOJ2208 [JSOI2010] 连通数


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2208

    Description

    Input

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

    Output

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

    Tarjan缩点+拓扑排序+bitset,mark[i][j]中的i表示第i个强连通分量,每一个点j对应mark[i][j/30+1]从右边数起第j%30位。

    每一个点与一个强连通分量连通的答案贡献值等于该强连通分量的大小

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <stack>
     6 #include <queue>
     7 #define rep(i,l,r) for(int i=l; i<=r; i++)
     8 #define clr(x,y) memset(x,y,sizeof(x))
     9 #define travel(x) for(int i=last[x]; i; i=edge[i].pre)
    10 #define travel2(x) for(int i=last2[x]; i; i=edge2[i].pre)
    11 using namespace std;
    12 const int maxn = 2010;
    13 struct Edge{
    14     int pre,to;
    15 }edge[maxn*maxn],edge2[maxn*maxn];
    16 int n,m,x,now,maxx,tot=0,tot2=0,ans=0,scc=0,dfsclock=0;
    17 int last[maxn],last2[maxn],dfn[maxn],low[maxn],belong[maxn],cnt[maxn],ind[maxn],mark[maxn][70];
    18 char ch[maxn];
    19 bool isin[maxn];
    20 stack <int> s;
    21 queue <int> q;
    22 inline void addedge(int x,int y){
    23     edge[++tot].pre = last[x];
    24     edge[tot].to = y;
    25     last[x] = tot;
    26 }
    27 inline void addedge2(int x,int y){
    28     edge2[++tot2].pre = last2[x];
    29     edge2[tot2].to = y;
    30     last2[x] = tot2;
    31     ind[y]++;
    32 }
    33 void tarjan(int x){
    34     dfn[x] = low[x] = ++dfsclock;
    35     isin[x] = 1; s.push(x);
    36     travel(x){
    37         if (!dfn[edge[i].to]){
    38             tarjan(edge[i].to);
    39             low[x] = min(low[x],low[edge[i].to]);
    40         }
    41         else if (isin[edge[i].to]) low[x] = min(low[x],dfn[edge[i].to]);
    42     }
    43     if (dfn[x] == low[x]){
    44         scc++;
    45         while (s.top() != x){
    46             isin[s.top()] = 0;
    47             belong[s.top()] = scc;
    48             cnt[scc]++;
    49             s.pop();
    50         }
    51         isin[x] = 0; belong[x] = scc; cnt[scc]++; s.pop();
    52     }
    53 }
    54 void toposort(){
    55     clr(mark,0);
    56     rep(i,1,n) mark[belong[i]][i/30+1] |= (1 << (i % 30));
    57     rep(i,1,scc) if (!ind[i]) q.push(i);
    58     while (!q.empty()){
    59         now = q.front(); q.pop();
    60         travel2(now){
    61             rep(j,1,maxx) mark[edge2[i].to][j] |= mark[now][j];
    62             ind[edge2[i].to]--;
    63             if (!ind[edge2[i].to]) q.push(edge2[i].to);
    64         }
    65     }
    66 }
    67 int main(){
    68     scanf("%d",&n); clr(last,0); clr(last2,0); clr(mark,0); maxx = n / 30 + 1;
    69     rep(i,1,n){
    70         scanf("%s",ch);
    71         rep(j,1,n) if (ch[j-1] - '0') addedge(i,j);
    72     }
    73     clr(isin,0); clr(dfn,0); clr(cnt,0);
    74     rep(i,1,n) if (!dfn[i]) tarjan(i);
    75     clr(ind,0);
    76     rep(now,1,n) travel(now) if (belong[now] != belong[edge[i].to])
    77         addedge2(belong[now],belong[edge[i].to]);
    78     toposort();
    79     rep(i,1,scc) rep(j,1,n)
    80     if (mark[i][j/30+1] & (1 << (j % 30))) ans += cnt[i];
    81     printf("%d
    ",ans);
    82     return 0;
    83 }
    View Code
  • 相关阅读:
    javascript模拟枚举
    javascript实现命名空间效果
    js数组去重
    文件上传插件
    script标签的defer属性
    js数组复制
    更改visual studio2010的主题
    关于json格式在.net前后台传值的详细示例
    where T : class泛型类型约束
    JavaScript模仿鼠标拖动选择功能
  • 原文地址:https://www.cnblogs.com/jimzeng/p/bzoj2208.html
Copyright © 2020-2023  润新知