BZOJ2208 [Jsoi2010]連通數 【圖的遍歷】
阿新 • • 發佈:2019-02-18
題目
輸入格式
輸入資料第一行是圖頂點的數量,一個正整數N。 接下來N行,每行N個字元。第i行第j列的1表示頂點i到j有邊,0則表示無邊。
輸出格式
輸出一行一個整數,表示該圖的連通數。
輸入樣例
3
010
001
100
輸出樣例
9
提示
對於100%的資料,N不超過2000。
題解
今晚水的題有點多。。。【明天要會考漲漲信心】
N才2000,可以
那從每個點出發跑一遍bfs看看能到哪些點就好了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u]; k != -1; k = ed[k].nxt)
using namespace std;
const int maxn = 2005,maxm = 5000005,INF = 1000000000;
inline int RD(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 1) + (out << 3) + c - '0'; c = getchar();}
return out * flag;
}
int h[maxn],ne = 0,ans = 0,n,vis[maxn];
struct EDGE{int to,nxt;}ed[maxm];
inline void build(int u,int v){ed[ne] = (EDGE){v,h[u]}; h[u] = ne++;}
queue <int> q;
void bfs(int u){
memset(vis,0,sizeof(vis));
q.push(u); vis[u] = true;
while (!q.empty()){
u = q.front(); q.pop();
ans++;
Redge(u) if (!vis[ed[k].to]) q.push(ed[k].to),vis[ed[k].to] = true;
}
}
int main(){
memset(h,-1,sizeof(h));
n = RD(); char c;
REP(i,n) REP(j,n){
c = getchar();
while (c != '1' && c != '0') c = getchar();
if (c == '1') build(i,j);
}
REP(i,n) bfs(i);
printf("%d\n",ans);
return 0;
}