BZOJ2419 电阻
记得这是高一的时候ty同学和我说的东西了。然后现在才解决,可以打败上帝造题的七分钟,荣登解决时间最长的题目了。
其实也就是一个高斯消元,用电势来列方程。不过高斯消元写得不熟,平时有空都写ds的题去了。以后不能再这样了。
用自己的代码高亮脚本了,虽然还不完善不过还是很开心的。
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> using namespace std; const int maxn = 109; const double inf = 1e100; const double eps = 1e-8; double x[maxn], a[maxn][maxn], b[maxn][maxn]; int n, m, perm[maxn]; int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); #endif srand(19970911); while (scanf("%d%d", &n, &m) != EOF) { for (int i = 1; i <= n; ++ i) perm[i] = i; if (n > 2) random_shuffle(perm + 2, perm + n); for (int i = 1; i <= n; ++ i) for (int j = 1; j <= n; ++ j) if (i == j) a[i][j] = 0; else a[i][j] = inf; while (m --) { int u, v; double p; scanf("%d%d%lf", &u, &v, &p); u = perm[u]; v = perm[v]; if (u == v) continue; a[u][v] = 1.0 / (1.0 / a[u][v] + 1.0 / p); a[v][u] = a[u][v]; } b[1][1] = 1; for (int i = 2; i <= n; ++ i) b[1][i] = 0; b[1][n + 1] = 0; for (int i = 2; i <= n; ++ i) { double sr(0); for (int j = 1; j <= n; ++ j) if (i != j) sr += 1.0 / a[i][j]; for (int j = 1; j <= n; ++ j) if (i == j) b[i][j] = - sr; else b[i][j] = 1.0 / a[i][j]; if (i == n) b[i][n + 1] = -1; else b[i][n + 1] = 0; } for (int i = 1; i <= n; ++ i) { int j0(i); for (int j = i + 1; j <= n; ++ j) if (abs(b[j0][i]) < abs(b[j][i])) j0 = j; if (j0 ^ i) for (int j = 1; j <= n + 1; ++ j) swap(b[i][j], b[j0][j]); for (int j = i + 1; j <= n; ++ j) { double rat(b[j][i] / b[i][i]); for (int k = 1; k <= n + 1; ++ k) b[j][k] -= b[i][k] * rat; } } printf("%.2lf\n", b[n][n + 1] / b[n][n]); } }