[BZOJ1778][Usaco2010 Hol]Dotp 驱逐猪猡:期望DP+高斯消元

分析:

类似于游走,又是有后效性DP的处理,当然要用到高斯消元。
注意图可能不连通。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>

int n,m,p,q;
int e[305][305],deg[305];
double sta,mov,eq[305][305];

inline void gauss(){
    for(int i=1;i<=n;i++){
        int r=i;
        for(int j=i+1;j<=n;j++)
            if(fabs(eq[j][i])>fabs(eq[r][i])) r=j;
        if(r!=i) for(int j=1;j<=n+1;j++) std::swap(eq[i][j],eq[r][j]);
        for(int j=1;j<=n;j++){
            if(i==j) continue;
            double t=eq[j][i]/eq[i][i];
            for(int k=1;k<=n+1;k++)
                eq[j][k]-=eq[i][k]*t;
        }
    }
}

int main(){
    scanf("%d%d%d%d",&n,&m,&p,&q);
    double sta=p*1.0/q,mov=1-sta;
    for(int i=1;i<=m;i++){
        int u,v;scanf("%d%d",&u,&v);
        e[u][v]++;
        e[v][u]++;
        deg[u]++;
        deg[v]++;
    }
    for(int i=1;i<=n;i++) eq[i][i]=-1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            if(!deg[j]) continue;
            eq[i][j]+=e[i][j]*mov/deg[j];
        }
    eq[1][n+1]=-1;
    gauss();
    for(int i=1;i<=n;i++)
        printf("%.9lf\n",fabs(sta*eq[i][n+1]/eq[i][i]));
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ErkkiErkko/p/9757218.html