從每個結點出發到每個後繼結點的概率均相等;
當執行完一個沒有後繼結點後,整個過程停止;
程序從編號爲1的結點開始執行;
你的任務是對於若干個查詢點,求出每個結點的期望執行次數;
思路:
本來以爲又是一個求普通求期望的題,像之前一樣迭代求解就行了;
後來發現有無窮大的解,看了大白,發現要高斯消元;
線性代數又忘得很厲害了;代碼基本照着敲的;
#include <cstring>
#include <cstdio>
#include <cmath>
#include <vector>
using namespace std;
const int maxn = 110;
const double eps = 1e-8;
typedef double Matrix[maxn][maxn];
Matrix A;
int n, d[maxn];
vector<int> pre[maxn];
int inf[maxn];
void gauss_jordan(Matrix A, int n) {
int i, j, k, r;
for (i = 0; i < n; i++) {
r = i;
for (j = i+1; j < n; j++)
if (fabs(A[j][i]) > fabs(A[r][i]))
r = j;
if (fabs(A[r][i]) < eps)
continue;
if (r != i)
for (j = 0; j <= n; j++)
swap(A[r][j], A[i][j]);
for (k = 0; k < n; k++)
if (i != k)
for (j = n; j >= i; j--)
A[k][j] -= A[k][i] / A[i][i] * A[i][j];
}
}
int main() {
int cas = 1;
while (scanf("%d", &n) != EOF && n) {
memset(d, 0, sizeof(d));
for (int i = 0; i < n; i++)
pre[i].clear();
int a, b;
while (scanf("%d%d", &a, &b) != EOF && a) {
a--, b--;
d[a]++;
pre[b].push_back(a);
}
memset(A, 0, sizeof(A));
for (int i = 0; i < n; i++) {
A[i][i] = 1;
for (int j = 0; j < pre[i].size(); j++)
A[i][pre[i][j]] -= 1.0 / d[pre[i][j]];
if (i == 0)
A[i][n] = 1;
}
gauss_jordan(A, n);
memset(inf, 0, sizeof(inf));
for (int i = n-1; i >= 0; i--) {
if (fabs(A[i][i]) < eps && fabs(A[i][n]) > eps)
inf[i] = 1;
for (int j = i+1; j < n; j++)
if (fabs(A[i][j]) > eps && inf[j])
inf[i] = 1;
}
int q, u;
scanf("%d", &q);
printf("Case #%d:\n", cas++);
while (q--) {
scanf("%d", &u);
u--;
if (inf[u])
printf("infinity\n");
else printf("%.3lf\n", fabs(A[u][u]) < eps ? 0.0 : A[u][n] / A[u][u]);
}
}
return 0;
}