美文网首页信息学竞赛题解(IO题解)
1491: [NOI2007]社交网络(Floyd)

1491: [NOI2007]社交网络(Floyd)

作者: AmadeusChan | 来源:发表于2018-10-17 12:04 被阅读0次

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1491

    貌似好久木有发过题解了?之前几天一直都在刷USACO月赛的水题,实在没什么可以写的,都是些模拟,水DP神马的,以后再来整理一下好了,废话少说了,对于这道题,刚开始想用n次SPFA搞,结果死活想不出来怎么处理路径数,然后去ORZ了一下BYVOID大神的BLOG之后才发现用FLOYD其实就够了,FLOYD的过程中顺便把最短路的数目处理出来,然后就乘法原理搞一下啦~

    代码:

    a8773912b31bb0512957b146347adab44aede069.jpg.png
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
     
    using namespace std ;
     
    #define MAXN 110
    #define rep( i , x ) for ( int i = 0 ; i ++ < x ; )
     
    const double inf = 1e20 ;
     
    double dist[ MAXN ][ MAXN ] , num[ MAXN ][ MAXN ] ;
    int n , m ; 
     
    int main(  ) {
        scanf( "%d%d" , &n , &m ) ; rep( i , n ) rep( j , n ) dist[ i ][ j ] = inf , num[ i ][ j ] = 0 ;
        while ( m -- ) {
            int s , t ; double d ; scanf( "%d%d%lf" , &s , &t , &d ) ;
            dist[ s ][ t ] = dist[ t ][ s ] = d , num[ s ][ t ] = num[ t ][ s ] = 1 ;
        }
        rep( k , n ) rep( i , n ) rep( j , n ) if ( dist[ i ][ k ] < inf && dist[ k ][ j ] < inf ) {
            if ( dist[ i ][ k ] + dist[ k ][ j ] < dist[ i ][ j ] ) {
                dist[ i ][ j ] = dist[ i ][ k ] + dist[ k ][ j ] ;
                num[ i ][ j ] = num[ i ][ k ] * num[ k ][ j ] ;
            } else if ( dist[ i ][ k ] + dist[ k ][ j ] == dist[ i ][ j ] ) {
                num[ i ][ j ] += num[ i ][ k ] * num[ k ][ j ] ;
            }
        }
        rep( i , n ) {
            double I = 0 ;
            rep( s , n ) rep( t , n ) if ( s != t && s != i && t != i && dist[ s ][ t ] == dist[ s ][ i ] + dist[ i ][ t ] ) {
                I += ( num[ s ][ i ] * num[ i ][ t ] ) / num[ s ][ t ] ;
            }
            printf( "%.3f\n" , I ) ;
        }
        return 0 ;
    }
    

    相关文章

      网友评论

        本文标题:1491: [NOI2007]社交网络(Floyd)

        本文链接:https://www.haomeiwen.com/subject/akglzftx.html