• [HNOI2013]游走


    [HNOI2013]游走

    考虑随机游走时一条边 $ (x,y) $ 被经过,只有两种情况,要么是我们走到了点 $ x $ ,然后随机钦定了 $ y $ ,要么就是反过来。我们假设一个点的度数为 $ deg[i] $ ,假设一个点期望会经过 $ t[u] $ 次,所以一个边所贡献的权值就是 $ w imes ( frac{t[x]}{deg[x]} + frac{t[y]}{deg[y]} ) $ 。

    所以现在我们的目标就是求 $ t $ 。发现 $ n leq 500 $ 我们可以考虑高消,具体而言,可以列出

    [t[u] = sum frac{t[v]}{deg[v]} ]

    特别的,对于第一个点必然会被经过一次, $ t[1] = 1 + sum frac{t[v]}{deg[v]} $ ,而 $ t[n] = 0 $,因为到达了 $ n $ 号点就结束了。

    #include "iostream"
    #include "algorithm"
    #include "cstring"
    #include "cstdio"
    #include "cmath"
    using namespace std;
    #define MAXN 506
    int n , m;
    #define eps 1e-6
    int deg[MAXN];
    double A[MAXN][MAXN];
    int gauss(  ) {
        for( int i = 1 ; i <= n ; ++ i ) { // cur : 第 i 行
            int mxpos = i;
            for( int j = i ; j <= n ; ++ j ) if( fabs( A[j][i] ) - fabs( A[mxpos][i] ) > eps )
                    mxpos = j;
            for( int j = 1 ; j <= n + 1 ; ++ j )
                swap( A[i][j] , A[mxpos][j] );
            double c = A[i][i];
            if( c == 0 ) { return 0; }
            A[i][i] = 1;
            for( int j = i + 1 ; j <= n + 1 ; ++ j )
                A[i][j] /= c;
            for( int j = 1 ; j <= n ; ++ j ) if( j != i ) { // cur : 第 j 行
                    double cc = A[j][i]; A[j][i] = 0;
                    for( int k = i + 1 ; k <= n + 1 ; ++ k ) // cur : 第 k 列
                        A[j][k] -= cc * A[i][k];
                }
        }
        return 1;
    }
    pair<int,int> E[MAXN * MAXN];
    double w[MAXN * MAXN];
    int G[MAXN][MAXN];
    int main() {
        cin >> n >> m;
        for( int i = 1 , u , v ; i <= m ; ++ i ) {
            scanf("%d%d",&u,&v);
            ++ deg[u] , ++ deg[v]; G[u][v] = G[v][u] = 1;
            E[i] = make_pair( u , v );
        }
        A[1][n + 1] = -1;
        for( int i = 1 ; i < n ; ++ i )
            for( int j = 1 ; j < n ; ++ j )
                if( G[i][j] )
                    A[i][j] = 1.0 / deg[j];
                else if( i == j ) A[i][j] = -1.0;
        A[n][n] = 1;
    //    for( int i = 1 ; i <= n ; ++ i ) {
    //        for (int j = 1; j <= n + 1; ++j) printf("%.3f ", A[i][j]); puts("");
    //    }
        gauss( );
    //    for( int i = 1 ; i <= n ; ++ i ) cout << A[i][n + 1] << endl;
        for( int i = 1 ; i <= m ; ++ i ) {
            int u = E[i].first , v = E[i].second;
            w[i] = A[u][n + 1] / deg[u] + A[v][n + 1] / deg[v];
        }
        sort( w + 1 , w + 1 + m );
        double res = 0;
        for( int i = 1 ; i <= m ; ++ i ) res += ( m - i + 1 ) * w[i];
        printf("%.3f",res);
    }
    
  • 相关阅读:
    Springboot + Atomikos + Druid + Mysql 实现JTA分布式事务
    JAVA生成一个二维数组,使中间元素不与相邻的9个元素相等,并限制每一个元素的个数
    java.net.UnknownHostException: lc001 未知的网络服务
    Maven 多模块引用版本的问题 java.lang.NoSuchMethodError
    Maven项目运行Junit测试用例 出现ClassNotFound
    CAS5.X 集群配置 初版
    调试CAS源码步骤
    openhtmltopdf 支持自定义字体、粗体
    Java HTML to PDF 支持SVG
    .Net 框架
  • 原文地址:https://www.cnblogs.com/yijan/p/12325655.html
Copyright © 2020-2023  润新知