zoukankan      html  css  js  c++  java
  • 小澳的葫芦

    题意:

    给出n(<=200)个点,m(<=2000)条边的有向无环图,每条边有个边权,问从1号节点到n号节点的路径上的 权值和 与 点数的最小比值

    题解:

    这个题有两种做法:

    一、

    定义dis[u][k]表示从1号节点到达u号点经过k个节点的最小权值和,用SPFA就可以完成,最后直接循环找一遍dis[n][k] / k的最小值

    二、

    但是以上只适用于点很少的情况,点多的情况一般采用以下套路~

    另建一个起点0,连接一条0到1长度为0的边,就此将问题转化为长度和边数最小比值。这个问题的求解需要分数规划。

    假设答案为ans,对于任意一条由k条边组成的路径,有:
    由 (w1 + w2 + w3 + … + wk) / k >= ans
    可以得到 : (w1 + w2 + w3 + … + wk) >= ans * k
    即(w1 - ans) + (w2 - ans) + (w3 - ans) + … + (wk - ans) >= 0

    于是就很容易想到

    二分答案x,每次将每一条边的权值减去x求最短路,判断1~n的最短路是否大于0

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    using namespace std;
    
    const int N = 2e2 + 7;
    const int M = 2e3 + 7;
    const double eps = 1e-9;
    
    int head[N], n, m, ecnt, inq[N];
    double dis[N];
    
    struct edge {
    	int v,nxt;
    	double w;
    }e[M];
    
    void adde (int u, int v, int w) {
    	e[ecnt].v = v;
    	e[ecnt].w = w;
    	e[ecnt].nxt = head[u];
    	head[u] = ecnt++;
    }
    
    int check (double x) {
    	for (int i = 0; i < ecnt; ++i) e[i].w -= x;
    	for (int i = 1; i <= n; ++i) dis[i] = 1e9 + 7, inq[i] = 0;
    	queue <int> q;
    	q.push(0), dis[0] = 0, inq[0] = 1;
    	while (!q.empty()) {
    		int u = q.front();
    		q.pop();
    		inq[u] = 0;
    		for (int it = head[u]; it != -1; it = e[it].nxt) {
    			int v = e[it].v;
    			if (dis[v] > dis[u] + e[it].w) {
    				dis[v] = dis[u] + e[it].w;
    				if (!inq[v]) {
    					q.push(v);
    					inq[v] = 1;
    				}
    			}
    		}
    	}
    	for (int i = 0; i < ecnt; ++i) e[i].w += x;
    	return dis[n] - eps < 0;
    }
    
    int main () {
    	scanf ("%d%d", &n, &m);
    	memset (head, -1, sizeof head);
    	adde (0, 1, 0);
    	for (int i = 1; i <= m; ++i) {
    		int u, v, w;
    		scanf ("%d%d%d", &u, &v, &w);
    		adde (u, v, w);
    	}
    	double l = 0, r = M;
    	while (l + eps < r) {
    		double mid = (l + r) / 2.0;
    		if (check (mid)) r = mid;
    		else l = mid;
    	}
    	printf ("%.3lf
    ", l);
    	return 0;
    }
    

      

  • 相关阅读:
    POJ 3083 Children of the Candy Corn
    工程投诉过程中各建设主管理部门联系人表
    Csharp:ListView paging and groups from Any Data Sources
    Csharp: Listview convert Datatable and ListView.Group count
    Csharp:Windowsform using CheckedListBox Datasource
    jquery.jclock.js using different time zone offsets
    在请求和响应中使用 XML
    zindex属性简介
    谁是管理软件的优秀客户?
    知识管理项目简述
  • 原文地址:https://www.cnblogs.com/xgtao/p/5964883.html
Copyright © 2011-2022 走看看