Description

给出一张有N个点M条边的加权有向无环图,接下来有Q个询问,每个询问包括2个节点X和Y,要求算出从X到Y的一条路径,使得密度最小(密度的定义为,路径上边的权值和除以边的数量)。

Input

第一行包括2个整数N和M。

以下M行,每行三个数字A、B、W,表示从A到B有一条权值为W的有向边。

再下一行有一个整数Q。

以下Q行,每行一个询问X和Y,如题意所诉。

Output

对于每个询问输出一行,表示该询问的最小密度路径的密度(保留3位小数),如果不存在这么一条路径输出“OMG!”(不含引号)。

Sample Input

3 3
1 3 5
2 1 6
2 3 6
2
1 3
2 3

Sample Output

5.000
5.500

Hint

1 ≤ N ≤ 50,1 ≤ M ≤ 1000,1 ≤ W ≤ 100000,1 ≤ Q ≤ 100000

题解

考虑转化成我们熟悉的问题解决。
由于都是求最小,很容易想到和此题类似的一个问题,求任两点间的最短路,能否借鉴 $Floyd$ 算法来解决呢?
本题不同点在于,还要除以一个边数。因为这个除法的缘故,使得 $Floyd$ 算法的最优子结构性质被破坏,假设存在路径 $i -> k -> j$,它的最小密度路径并不一定是 $i -> k$ 的最小密度路径加上 $k -> j$ 的最小密度路径。
例:设$[A, B]$表示路径的权值和为 $A$,通过了 $B$ 条边。假设从 $i -> k$ 存在着两条路径 $L1[2, 3]$以及 $L2[8, 10]$,从 $k -> j$ 存在着两条路径 $L3[1, 2]$以及 $L4[51, 100]$,很明显 $i -> k$ 的最小密度路径是 $L1$,$k -> j$ 的最小密度路径是 $L3$,但是 $i -> k -> j$ 的最小密度路径却是 $L1 + L4$。
有否办法去掉这个除法的影响?
回到问题特性,是有向无环图,一条路径最多只能经过 $N-1$条边,于是我们可以对边数进行枚举,即把答案的分母枚举了,剩下的就是让答案的分子最小化(答案是 权值和/边数),这就回到我们熟悉的问题:求最短。
在 $Floyd$ 的基础上重新划分阶段定义状态:

第 $k$ 个阶段表示恰好通过 $k$ 条边两点间的最短路,这样的话最优子结构以及无后效性都满足($k$ 的阶段的最优取值一定需要靠之前阶段的最优值,当然也不可能影响到之前阶段的取值了。)
定义状态 $f(i,j,k)$表示从 $i$ 到 $j$ 恰好经过 $k$ 条边的最短路,类似$Floyd$ 的算法得出 $DP$ 方程:
$$f(i,j,k)=Min(f(i,h,g)+f(h,j,k-g))$$
这个方程是 $5$ 维的,会超时,如何减小维数呢?
考虑在何处重复决策。注意到 $f(i,j,k)$的选择路径 $V1-V2-...-Vk$,实际上我们只要找到这里的一个点决策即可,而不需每个点都判断过去。这样就很容易想到在最后一个点进行决策。
$f(i,j,k)=Min(f(i,h,k-1)+f(h,j,1))$。数据范围不大,询问比较多,考虑用 $dp$ 直接算出所有点对的答案.因为密度 =$val \over R$ 所以考虑 $f[x][y][R]$ 为 $x=>y$ 经过 $R$ 条边的最小值 ,$ans={f[x][y][R] \over R}$
状态转移为:
$$f[i][j][R]=f[i][k][R-1]+f[k][j][1]$$

 //It is made by Awson on 2017.10.30
#include <set>
#include <map>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
using namespace std;
int INF;
const double eps = 1e-; int n, m, u, v, c;
int f[][][]; void work() {
memset(f, /, sizeof(f)); INF = f[][][];
scanf("%d%d", &n, &m);
while (m--) {
scanf("%d%d%d", &u, &v, &c);
f[u][v][] = Min(c, f[u][v][]);
}
for (int l = ; l < n; l++)
for (int k = ; k <= n; k++)
for (int i = ; i <= n; i++)
if (i != k)
for (int j = ; j <= n; j++)
if (j != k && j != i)
f[i][j][l] = Min(f[i][j][l], f[i][k][l-]+f[k][j][]);
scanf("%d", &m);
while (m--) {
scanf("%d%d", &u, &v);
if (u == v) {
printf("%.3lf\n", 0.0); continue;
}
double ans = INF;
for (int i = ; i < n; i++) if (f[u][v][i] != INF) ans = min(ans, (double)f[u][v][i]/(double)i);
if (abs(ans-INF) <= eps) printf("OMG!\n");
else printf("%.3lf\n", ans);
}
}
int main() {
work();
return ;
}

[Luogu 1730]最小密度路径的更多相关文章

  1. Luogu P1730 最小密度路径(最短路径+dp)

    P1730 最小密度路径 题面 题目描述 给出一张有 \(N\) 个点 \(M\) 条边的加权有向无环图,接下来有 \(Q\) 个询问,每个询问包括 \(2\) 个节点 \(X\) 和 \(Y\) , ...

  2. [洛谷P1730] 最小密度路径

    类型:Floyd 传送门:>Here< 题意:定义一条路径密度 = 该路径长度 / 边数.给出一张$DAG$,现有$Q$次询问,每次给出$X,Y$,问$X,Y$的最小密度路径($N \le ...

  3. 【洛谷P1730】最小密度路径

    题目大意:给定一个 N 个点,M 条边的有向图,现有 Q 个询问,每次询问 X 到 Y 的最小密度路径是多少.最小密度路径的定义是路径长度除以路径边数. 题解:利用矩阵乘法,可以预处理出从 X 到 Y ...

  4. 洛谷P1730 最小密度路径(floyd)

    题意 题目链接 Sol zz floyd. 很显然的一个dp方程\(f[i][j][k][l]\)表示从\(i\)到\(j\)经过了\(k\)条边的最小权值 可以证明最优路径的长度一定\(\leqsl ...

  5. 洛谷P1730最小密度路径

    题目传送门; 首先理解题目,究其本质就是一个最短路问题,而且数据范围贼水,用floyd完全没问题,但是题目有变化,要求出路径边权值与边数之比,这里就可以考虑在把floyd中的二维数组变为三维,f[ i ...

  6. Luogu 2764 最小路径覆盖问题 / Libre 6002 「网络流 24 题」最小路径覆盖 (网络流,最大流)

    Luogu 2764 最小路径覆盖问题 / Libre 6002 「网络流 24 题」最小路径覆盖 (网络流,最大流) Description 给定有向图G=(V,E).设P是G的一个简单路(顶点不相 ...

  7. luogu P2764 最小路径覆盖问题

    题目描述 给定有向图G=(V,E).设P 是G 的一个简单路(顶点不相交)的集合.如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖.P 中路径可以从V 的任何一个顶点开始,长度也是任 ...

  8. 求最大边/最小边的比值最小的路径 codevs 1001 舒适的路线

    codevs 1001 舒适的路线 2006年  时间限制: 2 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description Z小镇是一个景色宜人 ...

  9. HDU 4862 Jump(最小K路径覆盖)

    输入一个n×m网格图,每个结点的值为0-9,可以从任意点出发不超过k次,走完每个点且仅访问每个结点一次,问最终的能量最大值.不可全部走完的情况输出-1. 初始能量为0. 而结点(x,y)可以跳跃到结点 ...

随机推荐

  1. 听翁恺老师mooc笔记(16)--程序设计与C语言

    问题1:计算机遍布生活的各个方面,若你需要一个功能可以下载APP,我们需要的大部分功能都可以找到对应的APP,如果没有可以自己写一个软件,但是很少人需要这么做,那么我们为什么学习计算机编程语言? 学习 ...

  2. 201621123050 《Java程序设计》第4周学习总结

    1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 继承.抽象.多态 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一般不需要出现过多的字. 1.3 可选:使用常规方法 ...

  3. xcode修改代码目录结构出现clang:error:nosuchfileordirectory解决方法

    需要迁移一个开源工程的一部分内容到自己工程,迁移对方的工程到自己工程之后,因目录结构配置整理需要,对嵌入的工程目录进行了结构改变,编译后出现: clang: error: no such file o ...

  4. Flask 扩展 Flask-RESTful

    Flask路由可以指定HTTP请求方法,并在请求函数中根据不同的请求方法,执行不同的逻辑.这样实现一个Restful的请求已经相当简单了 Flask还有更简便的方法,就是其Flask-RESTful扩 ...

  5. fread函数详解

    函数原型: size_t   fread(   void   *buffer,   size_t   size,   size_t   count,   FILE   *stream   )    b ...

  6. 老板怎么办,我们网站遭到DDoS攻击又挂了?

    相信现在正在阅读此文的你,一定听说过发生在上个月的史上最大的DDoS攻击. 美国东部时间2月28日,GitHub在一瞬间遭到高达1.35Tbps的带宽攻击.这次DDoS攻击几乎可以堪称是互联网有史以来 ...

  7. linux cenots7安装mysql

        1.下载mysql 下载的话先确认好版本. system:centos7 mysql:5.7 下面的版本自己选择,一般是86位的. 下载好的文件 2.上传到服务器 soft文件夹,终端也进入了 ...

  8. django处理cookie的机制

    title: django处理cookie的机制 tags: djaogo, cookie, session grammar_cjkRuby: true --- cookie的意义 在多数日常使用的网 ...

  9. JavaScript正则表达式学习笔记(二) - 打怪升级

    本文接上篇,基础部分相对薄弱的同学请移步<JavaScript正则表达式学习笔记(一) - 理论基础>.上文介绍了8种JavaScript正则表达式的属性,本文还会追加介绍几种JavaSc ...

  10. Linux入门:usermod - 修改用户帐户信息

    一.什么是usermod? usermod 命令通过修改系统帐户文件来修改用户账户信息usermod [options] user_name选项(options)-a|--append ##把用户追加 ...