设概率转移矩阵为
An∗n
在爆炸概率矩阵
P
其中
设
B=p/q
即在每一时刻炸弹爆炸概率
有
P1∗n=B∗T1∗n∗Σ∞j=1(1−B)j−1∗Aj−1n∗n
设
Sn∗n=Σ∞j=1(1−B)j−1∗Aj−1n∗n
有
(1−B)∗Sn∗n∗An∗n=Σ∞j=2(1−B)j−1∗Aj−1n∗n
(1−B)∗Sn∗n∗An∗n=Σ∞j=1(1−B)j−1∗Aj−1n∗n−In∗n
其中I为单位矩阵
Sn∗n=In∗n∗(An∗n∗(1−B)−In∗n)−1
用高斯消元求出矩阵
(An∗n∗(1−B)−In∗n)
的逆矩阵即可
#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;
}