[BZOJ3534] [SDOI2014]再建(マトリックスツリー定理)

問題の表面を見るにはここをクリック

大雑把な質問の意味:あなたのマップを与えるために、それぞれの側は一定の確率が存在するがあります。図の需要は、単に確率のツリーとして存在しています。

どのような行列木定理

:あなたは、ツリー定理を行列していない場合は、我々はこのブログのこんにゃく見ることができ初級マトリックスツリー定理を

アプリケーションマトリックスツリー定理

この質問に、直接から\(P_ {I、J} \) ツリー定理行列を設定することは明らかに不可能です。

私たちは、すべての考える\(P_ {I、Jを} \) となり\(\ FRAC P_ {{I、J} {} {P_。1-I、J}} \) マトリックスツリー定理を適用し、最終的に乗じ\(\ prod_ 1} ^ {N-I = \ J = I {prod_。1} ^ N - +(1-P_ {I、Jは})\)、答えです。

この時点で、値のマトリックスと隣接行列の程度は、使用すべきである(\ FRACのP {1- \ P} \) 元交換する\(1 \)を

コード

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 50
#define DB double
#define eps 1e-8
using namespace std;
int n;double a[N+5][N+5];
class MatrixTreeSolver
{
    private:
        class Mat//矩阵
        {
            private:
                int n;DB v[N+5][N+5];
                I bool FindLine(CI x)
                {
                    for(RI i=x+1;i<=n;++i)
                    {
                        if(fabs(v[i][x])<eps) continue;
                        for(RI j=x;j<=n;++j) swap(v[x][j],v[i][j]);return true;
                    }return false;
                }
            public:
                I Mat(CI x=0):n(x){memset(v,0,sizeof(v));}
                I DB *operator [] (CI x) {return v[x];}
                I DB Det()//行列式
                {
                    RI i,j,k,op=1;DB t,res=1;for(i=1;i<=n;++i)
                    {
                        if(fabs(v[i][i])<eps&&(op*=-1,!FindLine(i))) return 0;res*=v[i][i];
                        for(j=i+1;j<=n;++j) for(t=v[j][i]/v[i][i],k=i;k<=n;++k) v[j][k]-=t*v[i][k];
                    }return op*res;
                }
        }S;
    public:
        I void Solve()
        {
            RI i,j;DB t,res=1;S=Mat(n-1);
            for(i=1;i<=n;++i) for(j=i+1;j<=n;++j)
                (t=1-a[i][j])<eps&&(t=eps),a[i][j]/=t,res*=t,//求出矩阵中这一位的值
                S[i][i]+=a[i][j],S[j][j]+=a[i][j],S[i][j]-=a[i][j],S[j][i]-=a[i][j];//求出度数矩阵减邻接矩阵
            printf("%.8lf",S.Det()*res);//求答案
        }
}T;
int main()
{
    RI i,j;for(scanf("%d",&n),i=1;i<=n;++i) for(j=1;j<=n;++j) scanf("%lf",&a[i][j]);//读入
    return T.Solve(),0;
}

おすすめ

転載: www.cnblogs.com/chenxiaoran666/p/BZOJ3534.html