https://vjudge.net/problem/UVA-10828
裸高斯消元。。。
但是要判无解和无穷解。
当出现一个环时会无解,环上每个点只有一个出边。
#includeusing namespace std; const int N = 110; const double eps = 1e-8; int n, q; double a[N][N], d[N]; vector<int> G[N]; int mark[N]; void build() { a[1][n + 1] = -1.0; for(int i = 1; i <= n; ++i) { a[i][i] = -1.0; for(int j = 0; j < G[i].size(); ++j) a[i][G[i][j]] += 1.0 / d[G[i][j]]; } } void gauss_jordan() { for(int now = 1; now <= n; ++now) { int x = now; for(int i = now + 1; i <= n; ++i) if(fabs(a[i][now]) > fabs(a[x][now])) x = i; if(fabs(a[x][now]) < eps) continue; for(int i = 1; i <= n + 1; ++i) swap(a[now][i], a[x][i]); double t = a[now][now]; for(int i = now; i <= n + 1; ++i) a[now][i] /= t; for(int i = 1; i <= n; ++i) if(i != now) { double t = a[i][now]; for(int j = now; j <= n + 1; ++j) a[i][j] -= a[now][j] * t; } } } int main() { int T = 0; while(scanf("%d", &n)) { ++T; if(n == 0) break; memset(d, 0, sizeof(d)); memset(a, 0, sizeof(a)); memset(mark, 0, sizeof(mark)); while(1) { int a, b; scanf("%d%d", &a, &b); if(a == 0 && b == 0) break; G[b].push_back(a); d[a] += 1.0; } build(); gauss_jordan(); for(int i = n; i; --i) { if(fabs(a[i][i]) < eps && fabs(a[i][n + 1]) > eps) mark[i] = 1; for(int j = i + 1; j <= n; ++j) if(fabs(a[i][j]) > eps && mark[j]) mark[i] = 1; } scanf("%d", &q); printf("Case #%d:\n", T); while(q--) { int x; scanf("%d", &x); if(mark[x]) puts("infinity"); else if(fabs(a[x][x]) < eps) puts("0.000"); else printf("%.3f\n", fabs(a[x][n + 1] / a[x][x])); } for(int i = 1; i <= n; ++i) G[i].clear(); } return 0; }