題意
有兩個人在無向圖中走,初始時在
分析
考慮兩個人會構成
則可以列出方程,設
設
- 注意到如果兩人在同一個房間的話就不可以再走了,所以當u==v的時候係數爲0
然後在狀態
高斯消元即可
#include <bits/stdc++.h>
#define maxn 10010
#define st(i, j) (i-1)*n+j
using namespace std;
int n, m;
int deg[maxn];
struct Edge{int to, next;}edge[maxn];
int h[maxn], cnt, s, t;
void add(int u, int v){
cnt ++;
edge[cnt].to = v;
edge[cnt].next = h[u];
h[u] = cnt;
deg[u] ++;
}
double p[maxn], Out[maxn];
double a[510][510];
void Debug(int n){
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= n + 1; j ++){
printf("%.2lf ", a[i][j]);
}printf("\n");
}puts("");
}
void build(int x, int y){
int now = st(x, y);
a[now][now] -= 1;
for(int i = h[x]; i; i = edge[i].next){
for(int j = h[y]; j; j = edge[j].next){
int u = edge[i].to, v = edge[j].to, to = st(u, v);
if(u != v){
if(u == x && v == y)a[now][to] += p[u] * p[v];
else if(u == x)a[now][to] += p[u] * Out[v];
else if(v == y)a[now][to] += Out[u] * p[v];
else a[now][to] += Out[u] * Out[v];
}
}
}
}
void Gauss(int n){
for(int i = 1; i <= n; i ++){
for(int j = i; j <= n; j ++)if(a[j][i]){
for(int k = 1; k <= n + 1; k ++)
swap(a[i][k], a[j][k]);
for(int k = 1; k <= n + 1; k ++)
if(k != i)a[i][k] /= a[i][i];
a[i][i] = 1;
break;
}
if(!a[i][i])continue;
for(int j = 1; j <= n; j ++){
if(j == i)continue;
double t = a[j][i];
for(int k = 1; k <= n + 1; k ++)
a[j][k] -= t * a[i][k];
}
}
}
int main(){
scanf("%d%d%d%d", &n, &m, &s, &t);
int u, v;
for(int i = 1; i <= m; i ++){
scanf("%d%d", &u, &v);
add(u, v), add(v, u);
}
for(int i = 1; i <= n; i ++)
scanf("%lf", &p[i]);
for(int i = 1; i <= n; i ++)
Out[i] = (1 - p[i]) / deg[i];
for(int i = 1; i <= n; i ++) add(i, i);
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= n; j ++)
build(i, j);
a[st(s, t)][n * n + 1] = -1;
Gauss(n * n);
for(int i = 1; i <= n; i ++){
int now = st(i, i);
printf("%.6lf ", a[now][n * n + 1]);
}
return 0;
}