BZOJ1778: [Usaco2010 Hol]Dotp 驅逐豬玀

設概率轉移矩陣爲Ann 在爆炸概率矩陣P 其中P1,i 爲 在點 i 爆炸概率 設行向量T1n= {1,0,0.. }(1n)
B=p/q 即在每一時刻炸彈爆炸概率
P1n=BT1nΣj=1(1B)j1Aj1nn
Snn=Σj=1(1B)j1Aj1nn

(1B)SnnAnn=Σj=2(1B)j1Aj1nn
(1B)SnnAnn=Σj=1(1B)j1Aj1nnInn
其中I爲單位矩陣
Snn=Inn(Ann(1B)Inn)1
用高斯消元求出矩陣(Ann(1B)Inn) 的逆矩陣即可

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;

long double A[601][601];
long double P[601][601];
long double I[601][601];

char c;
inline void read(int&a)
{
    a=0;do c=getchar();while(c<'0'||c>'9');
    while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
const
    long double eps=1e-16 ;
int n,m,p,q;
inline void Guass()
{
    for(int i=1;i<=n;i++)
    {
        int j=-1;
        for(int k=i;k<=n;k++)
            if(abs(P[k][i])>eps){j=k;break;}
        for(int k=0;k<=n;k++)
        {
            swap(P[i][k],P[j][k]),
            swap(I[i][k],I[j][k]);  
        }
        for(int k=i+1;k<=n;k++)
            if(abs(P[k][i])>eps)
            {
                long double a=P[k][i]/P[i][i];
                for(int t=0;t<=n;t++)
                    P[k][t]-=a*P[i][t],
                    I[k][t]-=a*I[i][t];

            }
    }
    for(int i=n;i;i--)
    {
        for(int j=0;j<=n;j++)
        if(i!=j)
            I[i][j]/=P[i][i],
            P[i][j]/=P[i][i];
        I[i][i]/=P[i][i];
        P[i][i]=1;
        for(int j=i-1;j;j--)
        {
            long double t=P[j][i];
            P[j][0]-=P[i][0]*P[j][i];
            for(int k=0;k<=n;k++)
            I[j][k]-=I[i][k]*t,

            P[j][i]-=P[j][i];   
        }
    }   
}
vector<pair<int,int> >Q ;
int d[4001];
int main()
{
    long double Bom;
    read(n),read(m),read(p),read(q);
    if(p==q)
    {
        printf("%.9f\n",1);
        for(int i=2;i<=n;i++)
        printf("%.9f\n",0);
        return 0;
    }
    Bom=p*1.0/q;
    for(int i=1;i<=m;i++)
    read(p),read(q),Q.push_back(make_pair(p,q)),d[p]++,d[q]++;
    for(int i=0;i<m;i++)
    {
        int x=Q[i].first,y=Q[i].second;
        P[x][y]+=1.0/d[x];
        P[y][x]+=1.0/d[y];
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            int x=i,y=j;
            A[x][y]=P[x][y];
            if(x==y)
            I[x][y]=1,P[x][y]=1-(1-Bom)*P[x][y];
            else P[x][y]=-(1-Bom)*P[x][y];
        }
    Guass();
    memset(P,0,sizeof(P));
    //for(int i=1;i<=n;i++)
    //  for(int j=1;j<=n;j++)
    //      for(int k=1;k<=n;k++)
    //          P[i][j]+=A[i][k]*I[k][j];
    for(int i=1;i<=n;i++)
    {
        double t=Bom*I[1][i];
        printf("%.9f\n",t);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章