bzoj 3270 博物館 高斯消元
阿新 • • 發佈:2018-08-14
inline n) int void online clu fine con zoj
題面
題目傳送門
解法
設\((x,y)\)表示第一個人在\(x\)房間,第二個人在\(y\)房間,然後列一個方程組即可
直接用高斯消元解一下就行了
時間復雜度:\(O(n^6)\)
代碼
#include <bits/stdc++.h> #define double long double #define eps 1e-9 #define N 410 using namespace std; int n, m, cnt, s[N], f[N][N]; double p[N], a[N][N]; int calc(int x, int y) {return (x - 1) * n + y;} void gauss(int n) { for (int i = 1; i <= n; i++) { if (fabs(a[i][i]) < eps) for (int j = i + 1; j <= n; j++) if (fabs(a[j][i]) > eps) for (int k = 1; k <= n + 1; k++) swap(a[i][k], a[j][k]); for (int j = i + 1; j <= n + 1; j++) a[i][j] /= a[i][i]; for (int j = 1; j <= n; j++) { if (i == j) continue; for (int k = i + 1; k <= n + 1; k++) a[j][k] -= a[j][i] * a[i][k]; } } } int main() { ios::sync_with_stdio(false); cin >> n >> m; int sx, sy; cin >> sx >> sy; cnt = n; for (int i = 1; i <= m; i++) { int x, y; cin >> x >> y; f[x][y] = f[y][x] = 1; s[x]++, s[y]++; } a[calc(sx, sy)][n * n + 1] = 1; for (int i = 1; i <= n; i++) cin >> p[i], f[i][i] = 1; for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { a[calc(i, j)][calc(i, j)] = 1; for (int x = 1; x <= n; x++) for (int y = 1; y <= n; y++) if (x != y && f[x][i] && f[y][j]) { double p1 = (x == i) ? p[x] : (1 - p[x]) / s[x]; double p2 = (y == j) ? p[y] : (1 - p[y]) / s[y]; a[calc(i, j)][calc(x, y)] -= p1 * p2; } } gauss(n * n); for (int i = 1; i <= n; i++) cout << fixed << setprecision(6) << a[calc(i, i)][n * n + 1] << ‘ ‘; return 0; }
bzoj 3270 博物館 高斯消元