bzoj1778
阿新 • • 發佈:2017-08-24
size rda names 成了 1.0 mes include lap jordan
高斯消元+矩陣的逆
來自popoqqq大神
求矩陣的逆:把I-T放在左邊,P/Q*S放在右邊,這樣就形成了一個n*2n的矩陣,然後把左邊高斯消元,右邊就是求完逆的矩陣,其實就是ans,矩陣的逆跟乘法逆元是一樣的,只不過是矩陣的逆元
然後輸出a[i][n+1],事實上矩陣只有n*(n+1)
構造轉移概率矩陣是a[u][v]=1.0/d[v]*(1-p/q),就是v->u的概率乘上在v不爆炸的概率
#include<bits/stdc++.h> using namespace std; const double eps = 1e-15; const int N = 610; int n, m;View Codedouble a[N][N]; double p, q, t; vector<int> G[N]; void gauss_jordan() { a[1][n + 1] = t; for(int i = 1; i <= n; ++i) { a[i][i] += 1.0; for(int j = 0; j < G[i].size(); ++j) { int u = G[i][j]; a[i][u] -= (1.0 - t) / (double)(G[u].size()); } }for(int now = 1; now <= n; ++now) { int x = now; for(int i = now; i <= n; ++i) if(fabs(a[i][now]) > fabs(a[x][now])) x = i; for(int i = 1; i <= n + 1; ++i) swap(a[now][i], a[x][i]); double t = a[now][now]; for(int i = 1; i <= n + 1; ++i) a[now][i] /= t;for(int i = 1; i <= n; ++i) if(fabs(a[i][now]) > eps && now != i) { t = a[i][now]; for(int j = 1; j <= n + 1; ++j) a[i][j] -= t * a[now][j]; } } for(int i = 1; i <= n; ++i) printf("%.9f\n", a[i][n + 1]); } int main() { scanf("%d%d%lf%lf", &n, &m, &p, &q); t = p / q; for(int i = 1; i <= m; ++i) { int u, v; scanf("%d%d", &u, &v); G[u].push_back(v); G[v].push_back(u); } gauss_jordan(); return 0; }
bzoj1778