zoukankan      html  css  js  c++  java
  • [BZOJ2208][Jsoi2010]连通数 暴力枚举

    Description

    Input

    输入数据第一行是图顶点的数量,一个正整数N。 接下来N行,每行N个字符。第i行第j列的1表示顶点i到j有边,0则表示无边。

    Output

    输出一行一个整数,表示该图的连通数。

    Sample Input


    010 
    001 
    100

    Sample Output

    9

    HINT

    对于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 , int v ) {
        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 ) ;
        }
        return ans ;
    }
    
    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
    " , i , ans - t ) ;
        }
        printf( "%lld
    " , ans ) ;
        return 0 ;
    } 
  • 相关阅读:
    关于session
    信息查找界面
    Java8 新特性 (三)Java内置的函数式接口
    第二节:表的管理
    【LeetCode-数组】有序数组中的单一元素
    【LeetCode-字符串】一次编辑
    【LeetCode-贪心】跳跃游戏 II
    【LeetCode-数组】三个数的最大乘积
    学习进度条94
    学习进度条93
  • 原文地址:https://www.cnblogs.com/henry-1202/p/BZOJ2208.html
Copyright © 2011-2022 走看看