zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    证券交易买进卖出手续费公式
    iOS学习之 plist文件的读写
    蓝桥杯——基础练习之字母图形
    SNMP协议具体解释
    Android开发框架SmartAndroid2.0 强劲框架
    隐藏快捷方式扩展名(.lnk)
    Filter及FilterChain的使用具体解释
    uva 1393
    深入浅出Windows BATCH
    科大讯飞2014公布会看点二:智能语音装进车载车机!
  • 原文地址:https://www.cnblogs.com/jimzeng/p/bzoj2208.html
Copyright © 2011-2022 走看看