博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
uva 10806 Dijkstra, Dijkstra. (最小费最大流)
阅读量:6509 次
发布时间:2019-06-24

本文共 2352 字,大约阅读时间需要 7 分钟。

uva 10806 Dijkstra, Dijkstra.

题目大意:你和你的伙伴想要越狱。你的伙伴先去探路,等你的伙伴到火车站后,他会打电话给你(电话是藏在蛋糕里带进来的),然后你就能够跑去火车站了,那里有人接应你。

可是。由于你的伙伴跑去火车站的时候穿的是囚服,所以,他经过的街道都被戒严了,你必须从其它街道跑过去。

假设你能够到达火车站,请输出你和你的伙伴在路上花费的最短时间,假设不能请“Back to jail”。

解题思路:最小费最大流。设置一个超级源点连向监狱(起点1), 容量为2(两个人),设置一个超级汇点,使火车站(终点n)连向他,容量为2(两个人)。其余街道皆为无向(即正向反向都要考虑)。且容量为1(每条街道仅仅能跑一次)。最后求最大流,若最大流为2则输出最小费,否则回监狱准备下次越狱吧。

#include 
#include
#include
#include
#include
#include
using namespace std;typedef long long ll;const int N = 105;const int INF = 0x3f3f3f3f;int n, m, s, t;int a[N], pre[N], d[N], inq[N]; struct Edge{ int from, to, cap, flow; ll cos;};vector
edges;vector
G[3 * N];void init() { for (int i = 0; i < 3 * N; i++) G[i].clear(); edges.clear();}void addEdge(int from, int to, int cap, int flow, ll cos) { edges.push_back((Edge){from, to, cap, 0, cos}); edges.push_back((Edge){to, from, 0, 0, -cos}); int m = edges.size(); G[from].push_back(m - 2); G[to].push_back(m - 1);}void input() { int from, to; ll cost; for (int i = 0; i < m; i++) { scanf("%d %d %lld", &from, &to, &cost); addEdge(from, to, 1, 0, cost); addEdge(to, from, 1, 0, cost); } addEdge(0, 1, 2, 0, 0); addEdge(n, n + 1, 2, 0, 0);}int BF(int s, int t, int& flow, ll& cost) { queue
Q; memset(inq, 0, sizeof(inq)); memset(a, 0, sizeof(a)); memset(pre, 0, sizeof(pre)); for (int i = 0; i <= 2 * n + 1; i++) d[i] = INF; d[s] = 0; a[s] = INF; inq[s] = 1; int flag = 1; pre[s] = 0; Q.push(s); while (!Q.empty()) { int u = Q.front(); Q.pop(); inq[u] = 0; for (int i = 0; i < G[u].size(); i++) { Edge &e = edges[G[u][i]]; if (e.cap > e.flow && d[e.to] > d[u] + e.cos) { d[e.to] = d[u] + e.cos; a[e.to] = min(a[u], e.cap - e.flow); pre[e.to] = G[u][i]; if (!inq[e.to]) { inq[e.to] = 1; Q.push(e.to); } } } flag = 0; } if (d[t] == INF) return 0; flow += a[t]; cost += (ll)d[t] * (ll)a[t]; for (int u = t; u != s; u = edges[pre[u]].from) { edges[pre[u]].flow += a[t]; edges[pre[u]^1].flow -= a[t]; } return 1;}int MCMF(int s, int t, ll& cost) { int flow = 0; cost = 0; while (BF(s, t, flow, cost)); return flow;}int main() { while (scanf("%d", &n) != EOF) { if (n == 0) break; scanf("%d", &m); s = 0, t = n + 1; init(); input(); ll cost = 0; int ans = MCMF(s, t, cost); if (ans == 1) printf("Back to jail\n"); else printf("%lld\n", cost); } return 0;}

转载地址:http://ldbfo.baihongyu.com/

你可能感兴趣的文章
monkey如何通过uiautomatorviewer的bounds坐标点击控件
查看>>
第22章,mysql数据库-1
查看>>
【亲测】教你如何搭建 MongoDB 复制集 + 选举原理
查看>>
虚拟化网络技术
查看>>
阿里云中间件推出全新开发者服务
查看>>
56.随机产生的id重复问题
查看>>
一个快速检测系统CPU负载的小程序
查看>>
java.lang.IllegalArgumentException: No bean specified
查看>>
Wireshark and Tcpdump tips
查看>>
第一课 计算机及操作系统基础知识
查看>>
windows2003单域迁移到2008R2服务器
查看>>
cacti相关资料网站
查看>>
我的友情链接
查看>>
网站的开发流程介绍(转)
查看>>
java面向对象中的方法重载与方法重写的区别
查看>>
浅析:Android--Fragment的懒加载
查看>>
Linux操作系统目录和Linux常用的文件和目录管理命令
查看>>
shell运算(加、减、乘、除)
查看>>
DIY:自己动手做一个迷你 Linux 系统(二)
查看>>
猫猫学IOS(三十)UI之Quartz2D画图片画文字
查看>>