zoukankan      html  css  js  c++  java
  • bzoj3143 [HNOI2013]游走

    题目链接

    solution

    如果可以统计出每条边期望走多少次,那么只要按照经过的次数从小到大降序编号就能保证最终得分最小了。

    统计每条边走的次数不好统计,但是统计点的经过次数似乎不难。那么边的经过次数就是他所连接的两点经过次数分别除以这两个点的度数之和。

    然后考虑如何统计每个点的经过次数。

    (f[i])表示(i)这个点被经过的次数。那么就有(f[u]=sumlimits_{w(u,v)}^n frac{f[v]}{du[v]})

    对于第一个点一开始就被经过了一次,所以有(f[1]=sumlimits_{w(1,v)}frac{f[v]}{du[v]}+1)。因为最后一个点只会被经过一次而且与最后一个点向连的边,最后一个点无法对其产生贡献,所以最后一个点不要考虑。

    列方程高斯消元解出来就行了。

    code

    /*
    * @Author: wxyww
    * @Date:   2020-04-27 20:14:39
    * @Last Modified time: 2020-04-27 20:25:22
    */
    #include<cstdio>
    #include<cmath>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<ctime>
    using namespace std;
    typedef long long ll;
    const int N = 510;
    ll read() {
    	ll x = 0,f = 1;char c = getchar();
    	while(c < '0' || c > '9') {
    		if(c == '-') f = -1; c = getchar();
    	}
    	while(c >= '0' && c <= '9') {
    		x = x * 10 + c - '0'; c = getchar();
    	}
    	return x * f;
    }
    struct node {
    	int v,nxt;
    }e[N * N];
    int head[N],ejs = 1;
    void add(int u,int v) {
    	e[++ejs].v = v;e[ejs].nxt = head[u];head[u] = ejs;
    }
    double a[N][N];
    int du[N];
    void Guass(int n) {
    	for(int i = 1;i <= n;++i) {
    		int t = i;
    		for(int j = i + 1;j <= n;++j)
    			if(a[j][i] > a[t][i]) t = j;
    
    		if(fabs(a[t][i]) < 1e-8) continue;
    		swap(a[t],a[i]);
    
    		double div = a[i][i];
    		for(int j = i;j <= n + 1;++j) a[i][j] /= div;
    
    		for(int j = 1;j <= n;++j) {
    			if(j == i) continue;
    			div = a[j][i];
    			for(int k = i;k <= n + 1;++k)
    				a[j][k] -= div * a[i][k]; 
    		}
    	}
    }
    
    double ans[N * N];
    int tot;
    int main() {
    	int n = read(),m = read();
    	for(int i = 1;i <= m;++i) {
    		int u = read(),v = read();
    		add(u,v);add(v,u);
    		du[u]++;du[v]++;
    	}
    
    	a[1][n] = 1;
    
    	for(int u = 1;u < n;++u) {
    		a[u][u] = 1;
    		for(int i = head[u];i;i = e[i].nxt ) {
    			int v = e[i].v;
    			if(v == n) continue;
    			a[u][v] -= 1.0 / du[v];
    		}
    	}
    
    	Guass(n - 1);
    
    	for(int i = 2;i <= ejs;i += 2)
    		ans[++tot] = a[e[i].v][n] / du[e[i].v] + a[e[i ^ 1].v][n] / du[e[i ^1].v];
    
    	sort(ans + 1,ans + tot + 1);
    	double anss = 0;
    	for(int i = 1;i <= tot;++i)
    		anss += ans[i] * (tot - i + 1);
    
    	printf("%.3lf
    ",anss);
    	return 0;
    }
    
  • 相关阅读:
    CF 461B Appleman and Tree
    POJ 1821 Fence
    NOIP 2012 开车旅行
    CF 494B Obsessive String
    BZOJ2337 XOR和路径
    CF 24D Broken robot
    POJ 1952 BUY LOW, BUY LOWER
    SPOJ NAPTIME Naptime
    POJ 3585
    CF 453B Little Pony and Harmony Chest
  • 原文地址:https://www.cnblogs.com/wxyww/p/bzoj3143.html
Copyright © 2011-2022 走看看