Description
Input
输入数据第一行是图顶点的数量,一个正整数N。 接下来N行,每行N个字符。第i行第j列的1表示顶点i到j有边,0则表示无边。
Output
输出一行一个整数,表示该图的连通数。
Sample Input
3
010
001
100
010
001
100
Sample Output
9
HINT
对于100%的数据,N不超过2000。
Tarjan缩一下点然后n²枚举计算答案
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define N (2000+10) 5 using namespace std; 6 struct node 7 { 8 int to,next; 9 }edge[N*N*2]; 10 int Dfn[N],dfs_num,Color[N],col_num; 11 int vis[N],stack[N],top,Low[N]; 12 int n,ans,head[N],num_edge; 13 char s[N]; 14 15 void add(int u,int v) 16 { 17 edge[++num_edge].to=v; 18 edge[num_edge].next=head[u]; 19 head[u]=num_edge; 20 } 21 22 void Tarjan(int x) 23 { 24 Dfn[x]=Low[x]=++dfs_num; 25 vis[x]=true; 26 stack[++top]=x; 27 for (int i=head[x];i;i=edge[i].next) 28 if (!Dfn[edge[i].to]) 29 { 30 Tarjan(edge[i].to); 31 Low[x]=min(Low[x],Low[edge[i].to]); 32 } 33 else 34 if (vis[edge[i].to]) 35 Low[x]=min(Low[x],Dfn[edge[i].to]); 36 if (Dfn[x]==Low[x]) 37 { 38 vis[x]=false; 39 Color[x]=++col_num; 40 while (stack[top]!=x) 41 { 42 vis[stack[top]]=false; 43 Color[stack[top--]]=col_num; 44 } 45 top--; 46 } 47 } 48 49 50 int main() 51 { 52 scanf("%d",&n); 53 for (int i=1;i<=n;++i) 54 { 55 scanf("%s",s); 56 for (int j=1;j<=n;++j) 57 if (s[j-1]==‘1‘) 58 add(i,j); 59 } 60 for (int i=1;i<=n;++i) 61 if (!Dfn[i]) 62 Tarjan(i); 63 for (int i=1;i<=n;++i) 64 for (int j=1;j<=n;++j) 65 if (Color[i]==Color[j]) 66 ++ans; 67 printf("%d",ans); 68 }