zoukankan      html  css  js  c++  java
  • [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;
    }
    
  • 相关阅读:
    map()和filter()函数讲解与示例
    通过假设巧妙的判断出参数的最大值和最小值
    通过函数定义数据结构list中的每个元素是一个元组,扑克牌示例
    FileCloud 的原理简述&自己搭建文件云
    opengl学习笔记
    Pascal的sin^-1函数实现
    OpenGL键盘交互响应事件
    OpenGL 鼠标交互响应事件
    重踏比尔盖茨走过的路——模拟操作系统
    Pascal代码自动格式化
  • 原文地址:https://www.cnblogs.com/hsuppr/p/3105906.html
Copyright © 2011-2022 走看看