[BZOJ2208][Jsoi2010]連通數 暴力枚舉
阿新 • • 發佈:2018-10-02
數組 sizeof tput efi pac cor jpg its search
010
001
100
Description
Input
輸入數據第一行是圖頂點的數量,一個正整數N。 接下來N行,每行N個字符。第i行第j列的1表示頂點i到j有邊,0則表示無邊。
Output
輸出一行一個整數,表示該圖的連通數。
Sample Input
3010
001
100
Sample Output
9HINT
對於100%的數據,N不超過2000。
Source
第一輪
Solution
好好的暴力不寫去寫什麽算法
雖然我也是學算法學傻了的,前兩天看到一道題說這不是莫隊裸題嗎,然後其實前綴和就行了
做法1:$tarjan$縮點+拓撲
做法2:$floyd$傳遞閉包
做法3:暴力$dfs$
因為我這人比較菜所以就寫做法3了
對於每個點直接開一個$vis$數組判斷有沒有到達過就可以了
比tarjan短多了
#include <bits/stdc++.h> using namespace std ; #define N 2010 #define ll long long int n , head[ N ] , cnt , vis[ N ] ; struct node { int to , nxt ; }e[ N * N ] ; void ins( int u , intv ) { e[ ++ cnt ].to = v ; e[ cnt ].nxt = head[ u ] ; head[ u ] = cnt ; } ll find( int u ) { ll ans = 1 ; vis[ u ] = 1 ; for( int i = head[ u ] ; i ; i = e[ i ].nxt ) { if( vis[ e[ i ].to ] ) continue ; ans += find( e[ i ].to ) ; } returnans ; } int main() { scanf( "%d" , &n ) ; for( int i = 1 ; i <= n ; i ++ ) { char ch[ 2010 ] ; scanf( "%s" , ch + 1 ) ; for( int j = 1 ; j <= n ; j ++ ) { if( ch[ j ] == ‘1‘ ) { ins( i , j ) ; } } } ll ans = 0 ; for( int i = 1 ; i <= n ; i ++ ) { memset( vis , 0 ,sizeof( vis ) ) ; ans += find( i ) ; // printf( "Case #%d : %d\n" , i , ans - t ) ; } printf( "%lld\n" , ans ) ; return 0 ; }
[BZOJ2208][Jsoi2010]連通數 暴力枚舉