• 【LG3232】[HNOI2013]游走


    题面

    洛谷

    题解

    img

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    inline int gi() {
        register int data = 0, w = 1;
        register char ch = 0;
        while (ch != '-' && (ch > '9' || ch < '0')) ch = getchar();
        if (ch == '-') w = -1 , ch = getchar();
        while (ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
        return w * data;
    }
    #define MAX_N 505 
    struct Edge {
    	int to, next; 
    } e[MAX_N * MAX_N << 1];
    int fir[MAX_N], cnt = 0;
    void clearGraph() {
    	memset(fir, -1, sizeof(fir));
    	cnt = 0; 
    }
    void Add_Edge(int u, int v) {
    	e[cnt].to = v, e[cnt].next = fir[u], fir[u] = cnt++; 
    }
    int N, M, d[MAX_N]; 
    double A[MAX_N][MAX_N]; 
    struct edg {
    	int u, v;
    	double P;
    	bool operator < (const edg & rhs) const {
            return P < rhs.P; 
    	} 
    } ed[MAX_N * MAX_N]; 
    int main () {
    	clearGraph();
    	N = gi(), M = gi();
    	for (int i = 1; i <= M; i++) {
    		int u = gi(), v = gi();
    		Add_Edge(u, v);
    		Add_Edge(v, u); 
    		d[u]++, d[v]++;
    		ed[i].u = u, ed[i].v = v; 
    	}
    	for (int i = 1; i <= N; i++) A[i][i] = 1.0; 
    	for (int x = 1; x < N; x++) 
    		for (int i = fir[x]; ~i; i = e[i].next) 
    			if (e[i].to != N) A[x][e[i].to] -= 1.0 / d[e[i].to]; 
    	A[1][N + 1] = 1; 
    	for (int i = 1; i <= N; i++) { 
    		int r = i; 
    		for (int j = i + 1; j <= N; j++) 
    			if (fabs(A[j][i]) > fabs(A[r][i])) r = j; 
    		if (r != i)
    			for (int j = 1; j <= N + 1; j++) swap(A[r][j], A[i][j]); 
    		for (int j = i + 1; j <= N; j++) { 
    			double f = A[j][i] / A[i][i]; 
    			for (int k = i; k <= N + 1; k++) A[j][k] -= f * A[i][k]; 
    		} 
    	}
    	for (int i = N; i >= 1; i--) {
    		for (int j = i + 1; j <= N; j++)
    			A[i][N + 1] -= A[j][N + 1] * A[i][j];
    		A[i][N + 1] /= A[i][i]; 
    	}
    	for (int i = 1; i <= M; i++) {
    		int u = ed[i].u, v = ed[i].v;
    		ed[i].P = 1.0 * A[u][N + 1] / d[u] + 1.0 * A[v][N + 1] / d[v]; 
    	}
    	
    	sort(&ed[1], &ed[M + 1]);
    	double ans = 0;
    	for (int i = 1; i <= M; i++) ans += ed[i].P * (M - i + 1.0);
    	printf("%0.3lf
    ", ans); 
    	return 0; 
    }
    
  • 相关阅读:
    Android编译环境配置(Ubuntu 14.04)
    Android中的接口回调技术
    我为什么要拒绝Ctrl+C和Ctrl+V?
    软件设计网站大全
    国内及Github优秀开发人员列表
    Linux常用指令
    Linux系统目录结构
    UML图
    Android软件设计---Dumpsys工具使用
    Android应用程序Monkey测试
  • 原文地址:https://www.cnblogs.com/heyujun/p/10405064.html
Copyright © 2020-2023  润新知