1. 题目
2. 题解
设 $f[x]$表示从 $1$号点一直游走,游走到点 $x$都一直没有爆炸的概率。
$f[x]=(1 – \frac P Q) \sum {\frac {f[v]} {degree[v]}} + [u == 1]$
其中 $degree$表示一个点的度数,$[u == 1]$表示 $u$是否是 $1$号点,如果是则值为 $1$,否则为 $0$。
特判是否等于 $1$是因为起点是 $1$,因此其实直接说概率是不太严谨的,应该算一种期望吧。
然后高斯消元就行啦。
代码:
#include <bits/stdc++.h>
#define NS (305)
using namespace std;
template<typename _Tp> inline void IN(_Tp& dig)
{
char c; bool flag = 0; dig = 0;
while (c = getchar(), !isdigit(c)) if (c == '-') flag = 1;
while (isdigit(c)) dig = dig * 10 + c - '0', c = getchar();
if (flag) dig = -dig;
}
int n, m, p, q;
vector<int> g[NS];
double frc, d[NS][NS];
void Gs()
{
for (int i = 1; i <= n; i += 1)
{
for (int j = i + 1; j <= n; j += 1)
if (d[i][i] < d[j][i]) swap(d[i], d[j]);
for (int j = n + 1; j >= i; j -= 1)
d[i][j] /= d[i][i];
for (int j = i + 1; j <= n; j += 1)
for (int k = n + 1; k >= i; k -= 1)
d[j][k] -= d[j][i] * d[i][k];
}
for (int i = n; i >= 1; i -= 1)
for (int j = 1; j < i; j += 1)
d[j][n + 1] -= d[i][n + 1] * d[j][i];
}
int main(int argc, char const* argv[])
{
IN(n), IN(m), IN(p), IN(q), frc = (double)p / q;
for (int i = 1, a, b; i <= m; i += 1)
IN(a), IN(b), g[a].push_back(b), g[b].push_back(a);
for (int i = 1; i <= n; i += 1)
{
d[i][i] = 1;
for (int j = 0; j < g[i].size(); j += 1)
d[i][g[i][j]] = (frc - 1) / g[g[i][j]].size();
if (i == 1) d[i][n + 1] = 1;
}
Gs();
for (int i = 1; i <= n; i += 1)
printf("%.9lf\n", d[i][n + 1] * frc);
return 0;
}
0 条评论