[题目链接]

[算法]

记fi,j表示第一个人在i ， 第二个人在j的概率

高斯消元即可

时间复杂度 : O(N ^ 6)

[代码]

#include<bits/stdc++.h>
using namespace std;
const int N = 30;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
const double eps = 1e-9;

struct edge
{
int to , nxt;
} e[N * N * 2];

int n , m , A , B , tot;
double deg[N * N] , a[N * N][N * N] , b[N * N] , p[N * N] , ans[N * N];

template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
template <typename T> inline void read(T &x)
{
T f = 1; x = 0;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
x *= f;
}
inline int id(int x , int y)
{
return (x - 1) * n + y;
}
inline void addedge(int u , int v)
{
++tot;
}
int dcmp(double x)
{
if (x<=eps&&x>=-eps) return 0;
return (x>0)?1:-1;
}

int main()
{

scanf("%d%d%d%d" , &n , &m , &A , &B);
for (int i = 1; i <= m; i++)
{
int u , v;
scanf("%d%d" , &u , &v);
deg[u] += 1.0;
deg[v] += 1.0;
}
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++)
{
a[id(i , j)][id(i , j)] = 1;
if (i != j) a[id(i , j)][id(i , j)] -= p[i] * p[j];
for (int k = head[i]; k; k = e[k].nxt)
if (e[k].to != j && e[k].to != i) a[id(i , j)][id(e[k].to , j)] -= (1 - p[e[k].to]) / deg[e[k].to] * p[j];
for (int k = head[j]; k; k = e[k].nxt)
if (i != e[k].to && j != e[k].to) a[id(i , j)][id(i , e[k].to)] -= (1 - p[e[k].to]) / deg[e[k].to] * p[i];
for (int k = head[i]; k; k = e[k].nxt)
{
for (int l = head[j]; l; l = e[l].nxt)
{
if (e[k].to != e[l].to)
a[id(i , j)][id(e[k].to , e[l].to)] -= (1 - p[e[k].to]) / deg[e[k].to] * (1 - p[e[l].to]) / deg[e[l].to];
}
}
}
}
b[id(A , B)] = 1.0;
for (int i=1;i<=n*n;++i)
{
int num=i;
for (int j=i+1;j<=n*n;++j)
if (dcmp(a[j][i]-a[num][i])>0) num=j;
if (num!=i)
{
for (int j=1;j<=n*n;++j) swap(a[num][j],a[i][j]);
swap(b[num],b[i]);
}
for (int j=i+1;j<=n*n;++j)
if (dcmp(a[j][i]))
{
double t=a[j][i]/a[i][i];
for (int k=1;k<=n*n;++k)
a[j][k]-=t*a[i][k];
b[j]-=b[i]*t;
}
}
for (int i=n*n;i>=1;--i)
{
for (int j=i+1;j<=n*n;++j) b[i]-=a[i][j]*ans[j];
ans[i]=b[i]/a[i][i];
}
for (int i = 1; i <= n; i++) printf("%.6lf " , ans[id(i , i)]);
printf("\n");

return 0;
}