令 f(x,y) 为一个人在x一个人在y的概率(与f(y,x)不同)
有四种转移
f(x,y)∗p[x]∗p[y]→f(x,y)
f(x,y)∗p[x]∗(1−p[y])/d[y]→f(x,v)
,
v
为与
f(x,y)∗(1−p[x])∗p[y]/d[x]→f(u,y)
,
u
为与
f(x,y)∗(1−p[x])∗(1−p[y])/d[x]/d[y]→f(u,v)
可以列出方程组
⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪a11f(x1,y1)+a12f(x2,y2)+...+a1nf(xn,yn)=f(u1,v1)a21f(x1,y1)+a22f(x2,y2)+...+a2nf(xn,yn)=f(u2,v2)...a31f(x1,y1)+a32f(x2,y2)+...+a3nf(xn,yn)=f(u3,v3)
用高斯消元解出答案
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
#include <iostream>
#define eps 1e-7
#define g(a,b) ((a-1)*n+b)
using namespace std;
int n,m,a,b,cnt,u,v,t,w,tot;
int d[25];
double A[410][410];
double p[25];
vector<int> E[25];
inline void Insert(int u,int v){
E[u].push_back(v); E[v].push_back(u);
d[u]++; d[v]++;
}
inline void check(int x,int y){
double *B=A[g(x,y)];
B[g(x,y)]=-1;
for(int i=0;i<(int)E[x].size();i++)
for(int j=0;j<(int)E[y].size();j++){
u=E[x][i]; v=E[y][j]; w=g(u,v);
if(u!=v){
if(u==x&&v==y) B[w]+=p[u]*p[v];
else if(u==x) B[w]+=p[u]*(1-p[v])/d[v];
else if(v==y) B[w]+=p[v]*(1-p[u])/d[u];
else B[w]+=(1-p[u])*(1-p[v])/d[v]/d[u];
}
}
}
inline void gauss(){
int now=1;
for(int i=1,j,k;i<=tot;i++){
for(j=now;j<=tot&&fabs(A[j][i])<eps;j++);
if(j>tot) continue;
if(j!=now) for(k=1;k<=tot+1;k++) swap(A[j][k],A[now][k]);
double t=A[now][i];
for(j=1;j<=tot+1;j++) A[now][j]/=t;
for(j=1;j<=tot;j++)
if(j!=now){
t=A[j][i];
for(k=1;k<=tot+1;k++) A[j][k]-=t*A[now][k];
}
now++;
}
}
int main(){
scanf("%d%d%d%d",&n,&m,&a,&b);
tot=n*n;
A[g(a,b)][tot+1]=-1;
for(int i=1;i<=n;i++) E[i].push_back(i);
for(int i=1;i<=m;i++){
scanf("%d%d",&u,&v);
Insert(u,v);
}
for(int i=1;i<=n;i++) scanf("%lf",&p[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
check(i,j);
gauss();
for(int i=1;i<=n;i++) printf("%.6lf ",A[g(i,i)][tot+1]);
}