题目描述
度量一个有向图联通情况的一个指标是连通数,指图中可达顶点对个的个数。
如图
顶点 111 可达 1, 2, 3, 4, 51,~2,~3,~4,~51, 2, 3, 4, 5
顶点 222 可达 2, 3, 4, 52,~3,~4,~52, 3, 4, 5
顶点 333 可达 3, 4, 53,~4,~53, 4, 5
顶点 4, 54,~54, 5 都只能到达自身。
所以这张图的连通数为 141414。
给定一张图,请你求出它的连通数
输入格式
输入数据第一行是图顶点的数量,一个正整数N。 接下来N行,每行N个字符。第i行第j列的1表示顶点i到j有边,0则表示无边。
输出格式
输出一行一个整数,表示该图的连通数。
输入输出样例
输入 #1复制
3 010 001 100
输出 #1复制
9
说明/提示
对于100%的数据,N不超过2000。
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <bitset>
using namespace std;
typedef long long ll;
const int N = 2010;
bitset<N> mp[N];
int n;
char s[N]; //不知道为什么用string输入会RE
void floyd()
{
for(int k = 0; k < n; ++k)
{
for(int i = 0; i < n; ++i)
{
if(mp[i][k])
{
mp[i] |= mp[k];
}
}
}
}
int main()
{
while(~scanf("%d", &n))
{
for(int i = 0; i < n; ++i)
{
scanf("%s", &s);
for(int j = 0; j < n; ++j)
{
mp[i][j] = s[j] - '0';
}
mp[i][i] = 1;
}
floyd();
int ans = 0;
for(int i = 0; i < n; ++i)
{
ans += mp[i].count();
}
cout<<ans<<'\n';
}
return 0;
}