【luoguP1730】最小密度路径
来源:互联网 发布:教育大数据应用 编辑:程序博客网 时间:2024/05/11 01:53
题目描述
给出一张有N个点M条边的加权有向无环图,接下来有Q个询问,每个询问包括2个节点X和Y,要求算出从X到Y的一条路径,使得密度最小(密度的定义为,路径上边的权值和除以边的数量)。
输入输出格式
输入格式:第一行包括2个整数N和M。
以下M行,每行三个数字A、B、W,表示从A到B有一条权值为W的有向边。
再下一行有一个整数Q。
以下Q行,每行一个询问X和Y,如题意所诉。
输出格式:对于每个询问输出一行,表示该询问的最小密度路径的密度(保留3位小数),如果不存在这么一条路径输出“OMG!”(不含引号)。
输入输出样例
输入样例#1:
3 31 3 52 1 62 3 621 32 3
输出样例#1:
5.0005.500
说明
1 ≤ N ≤ 10,1 ≤ M ≤ 100,1 ≤ W ≤ 1000,1 ≤ Q ≤ 1000
01分数规划裸题
首先考虑一下二分答案ans
如果有存在
ans > Σw[i] / cnt 即 Σ(w[i] - ans) / cnt < 0的情况
那么答案不合法,反之答案合法
然后spfa跑一跑就好了
代码:
#include<cstdio>#include<algorithm>#include<cstring>#include<vector>#include<queue>using namespace std;typedef double DL;const int INF = 2147483647;const int maxn = 100;struct data{ int to,w; DL v;};queue<int> Q;vector<data> e[maxn];int n,m;DL dis[maxn];bool exist[maxn],vis[maxn];DL ans[maxn][maxn];inline int getint(){ int ret = 0,f = 1; char c = getchar(); while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); } while (c >= '0' && c <= '9') ret = ret * 10 + c - '0',c = getchar(); return ret * f;}inline bool spfa(int s,int t){ for (int i = 1; i <= n; i++) dis[i] = INF; dis[s] = 0; Q.push(s); while (!Q.empty()) { int u = Q.front(); exist[u] = 0; Q.pop(); for (int i = 0; i < e[u].size(); i++) { int v = e[u][i].to; DL w = e[u][i].v; if (dis[v] > dis[u] + w) { dis[v] = dis[u] + w; if (!exist[v]) { Q.push(v); exist[v] = 1; } } } } return dis[t] <= 0;}inline void rebuild(DL x){ for (int i = 1; i <= n; i++) for (int j = 0; j < e[i].size(); j++) e[i][j].v = (DL)(e[i][j].w) - x;}inline DL binary(int u,int v){ DL l = 0,r = 1000; for (int i = 1; i <= 30; i++) { DL mid = (l + r) / 2; rebuild(mid); if (spfa(u,v)) r = mid; else l = mid; } return l;}inline bool dfs(int u,int t){ vis[u] = 1; if (u == t) return 1; for (int i = 0; i < e[u].size(); i++) { int v = e[u][i].to; if (vis[v]) continue; if (dfs(v,t)) return 1; } return 0;}int main(){ n = getint(); m = getint(); for (int i = 1; i <= m; i++) { int u = getint(),v = getint(),w = getint(); e[u].push_back((data){v,w}); } for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) { if (i == j) continue; memset(vis,0,sizeof(vis)); if (!dfs(i,j)) {ans[i][j] = -1; continue;} ans[i][j] = binary(i,j); } int q = getint(); for (int i = 1; i <= q; i++) { int u = getint(),v = getint(); if (ans[u][v] == -1) printf("OMG!\n"); else printf("%0.3lf\n",ans[u][v]); } return 0;}
阅读全文
0 0
- 【luoguP1730】最小密度路径
- P1730 最小密度路径
- 最小密度路径 洛谷 1730
- [模板题] 最小密度路径
- P1730 Floyed 最小密度路径
- 【改进floyed】最小密度路径(path)
- 最小密度路径_洛谷1730
- 【NOIP2016模拟赛No.1】 最小密度路径
- 【最小路径】
- 最小路径
- 【最小路径覆盖】最小路径覆盖
- POJ 3155 最大密度子图 二分+最小割
- poj3155 Hard Life 最小割 最大密度子图
- codeforces 444 A. DZY Loves Physics (图的最小密度)
- 最小路径覆盖
- 最小路径覆盖
- pku2594 最小路径覆盖
- 最小路径覆盖
- 【CUGBACM15级BC第12场 B】hdu 5059 Help him
- C# 初步学习线程
- OAuth2.0
- 图书馆管理系统
- CSS字体相关属性
- 【luoguP1730】最小密度路径
- 数据库SQL实战
- webservice之axis2客户端调用(maven方式创建java项目)
- 51nod 1097 拼成最小的数
- spring的零配置
- [js]css导航栏细究
- 欢迎使用CSDN-markdown编辑器
- HDU 1892 See you~ (二维树状数组)
- TP框架中D方法与M方法的区别