[HNOI2013]游走
一看就是高斯消元。
但没想到边的期望经过次数=点的期望 / 点的度数
官方数据有误。
我的代码在gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 下可以过。
在 gcc 4.6.3 g++ Main.cc -o Main -Wall -lm --static -DONLINE_JUDGE 下可以过 (去掉-O2)
/** * Problem:HNOI2013-d2p2 * Author:Shun Yao * Time:2013.5.28 * Result:Accepted * Memo:DP, greedy, guass */ #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm> const long Maxn = 505; long n, m, d[Maxn]; double a[Maxn][Maxn], w[Maxn]; class lnode { public: long u, v; lnode() {} ~lnode() {} } line[Maxn * Maxn >> 1]; bool cmpa(double x, double y) { return x > y; } int main() { freopen("d2p2.in", "r", stdin); freopen("d2p2.out", "w", stdout); scanf("%ld%ld", &n, &m); memset(d, 0, sizeof d); for (long i = 1; i <= m; ++i) { scanf("%ld%ld", &line[i].u, &line[i].v); ++d[line[i].u]; ++d[line[i].v]; } for (long i = 1; i < n; ++i) a[i][i] = 1.0; a[1][0] = 1.0; for (long i = 1; i <= m; ++i) { if (line[i].u == n || line[i].v == n) continue; a[line[i].u][line[i].v] -= 1.0 / d[line[i].v]; a[line[i].v][line[i].u] -= 1.0 / d[line[i].u]; } for (long i = 1; i < n; ++i) { long pos; for (long j = i; j < n; ++j) { if (fabs(a[j][i]) > 1e-16) { pos = j; break; } } if (pos != i) { std::swap(a[pos][0], a[i][0]); for (long j = i; j < n; ++j) std::swap(a[pos][j], a[i][j]); } for (long j = i + 1; j < n; ++j) if (fabs(a[j][i]) > 1e-16) { double x = a[j][i] / a[i][i]; a[j][0] -= a[i][0] * x; for (long k = i; k < n; ++k) a[j][k] -= a[i][k] * x; } } for (long i = n - 1; i; --i) { for (long j = i + 1; j < n; ++j) a[i][0] -= a[i][j] * a[j][0]; a[i][0] /= a[i][i]; } for (long i = 1; i <= m; ++i) w[i] = a[line[i].u][0] / d[line[i].u] + a[line[i].v][0] / d[line[i].v]; std::sort(w + 1, w + m + 1, cmpa); double ans = 0.0; for (long i = 1; i <= m; ++i) ans += i * w[i]; printf("%.3lf", ans); fclose(stdin); fclose(stdout); return 0; }
作者:HSUPPR
出处:http://www.cnblogs.com/hsuppr/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出
原文链接,否则保留追究法律责任的权利。