SGU 185.Two shortest (最小费用最大流)
时间限制:0.25s
空间限制:4M
题意:
在n(n<=400)个点的图中,找到并输出两条不想交的最短路。不存在输出“No sulotion”;
Solution:
最小费用最大流
建图与poj 2135 一样,添加S到1的流量为2权为0,n到T的流量为2权为0的边,其它边的流量为1,权为路径长度.
但是这道题麻烦不在要输出最短路,而在仅仅4M的内存上。
由于只有4M,我们最多存上400*400条边.但是图却是一个无向图,朴素的想法是存上400*400*2条边,但是这里内存不够.
所以我们首先要确定记录一条边我们是否使用过,如果使用了使用的是那个方向.
相应的在找到增广路后,把正向反向边的流量改变,把反向边的费用变成负值.
最后按照我们标记过的边dfs,并输出就好了.
总的来说是一道足以加深对最小费用最大流的理解的不错的题!
参考代码:
- /*
- 最小费用最大流算法:
- 思路:
- 以费用为权做最短路算法。
- */
- #include <iostream>
- #include <cstdio>
- #include <queue>
- #include <cstring>
- #include <cmath>
- using namespace std;
- const int INF = , Maxn = 0x3f3f3f3f;
- struct node {
- int u, v, t, c, next;
- } edge[INF * INF];
- int head[INF], nCnt = ;
- int G[INF][INF];
- void addEdge (int u, int v, int traffic, int cost) {
- edge[++nCnt].v = v, edge[nCnt].u = u, edge[nCnt].t = traffic, edge[nCnt].c = cost;
- edge[nCnt].next = head[u], head[u] = nCnt;
- edge[++nCnt].v = u, edge[nCnt].u = v, edge[nCnt].t = traffic, edge[nCnt].c = cost;
- edge[nCnt].next = head[v], head[v] = nCnt;
- }
- int max_flow, min_cost;
- int n, m, SS, ST, S, T, min_dis = Maxn;
- int SPFA() {
- queue<int> ql;
- int vis[INF] = {}, dis[INF], pre[INF] = {};
- ql.push (SS);
- memset (dis, 0x3f, sizeof dis);
- vis[SS] = , dis[SS] = ;
- while (!ql.empty() ) {
- int x = ql.front(); ql.pop();
- for (int i = head[x]; i != ; i = edge[i].next) {
- if (edge[i].t == ) continue;
- int v = edge[i].v, c = edge[i].c;
- if (dis[v] > dis[x] + c) {
- dis[v] = dis[x] + c;
- pre[v] = i;
- if (!vis[v])
- ql.push (v), vis[v] = ;
- }
- }
- vis[x] = ;
- }
- min_dis = min (min_dis, dis[ST]);
- if (dis[ST] == Maxn) return ;
- else {
- min_cost += dis[ST];
- int k = pre[ST];
- int cur_flow = Maxn;
- while (k) {
- if (cur_flow > edge[k].t) cur_flow = edge[k].t;
- G[edge[k].u][edge[k].v] = G[edge[k].v][edge[k].u] = ^ G[edge[k].v][edge[k].u];
- edge[k].t = edge[k ^ ].t, edge[k].c = abs (edge[k].c);
- edge[k ^ ].t = , edge[k ^ ].c = -abs (edge[k ^ ].c);
- k = pre[edge[k].u];
- }
- max_flow += cur_flow;
- k = pre[ST];
- while (k) {
- edge[k].t -= cur_flow, edge[k ^ ].t += cur_flow;
- k = pre[edge[k].u];
- }
- return ;
- }
- }
- void dfs (int x) {
- for (int i = head[x]; i != ; i = edge[i].next) {
- if (G[x][edge[i].v] && edge[i].t > && edge[i].v < T) {
- edge[i].t = ;
- dfs (edge[i].v);
- break;
- }
- }
- if (x == S) printf ("%d", x);
- else
- printf (" %d", x);
- }
- int MCMF() {
- while (SPFA() );
- if (max_flow == && min_cost == * min_dis) {
- dfs (T);
- putchar ();
- dfs (T);
- }
- else
- puts ("No solution");
- }
- void build() {
- scanf ("%d %d", &n, &m);
- int x, y, z;
- for (int i = ; i <= m; i++) {
- scanf ("%d %d %d", &x, &y, &z);
- addEdge (x, y, , z);
- }
- S = , T = n;
- SS = n + , ST = n + ;
- addEdge (SS, S, , ), addEdge (T, ST, , );
- }
- int main() {
- build();
- MCMF();
- return ;
- }
SGU 185.Two shortest (最小费用最大流)的更多相关文章
- SGU 185 Two shortest 最短路+最大流
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=21068 Yesterday Vasya and Petya qua ...
- TZOJ 4712 Double Shortest Paths(最小费用最大流)
描述 Alice and Bob are walking in an ancient maze with a lot of caves and one-way passages connecting ...
- CSU 1506 Problem D: Double Shortest Paths(最小费用最大流)
题意:2个人从1走到n,假设一条路第一次走则是价值di,假设第二次还走这条路则须要价值di+ai,要你输出2个人到达终点的最小价值! 太水了!一条边建2次就OK了.第一次价值为di,第二次为ai+di ...
- POJ 2516 最小费用最大流
每一种货物都是独立的,分成k次最小费用最大流即可! 1: /** 2: 因为e ==0 所以 pe[v] pe[v]^1 是两条相对应的边 3: E[pe[v]].c -= aug; E[pe[v]^ ...
- 网络流(最小费用最大流):POJ 2135 Farm Tour
Farm Tour Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: ...
- UVa 10806 Dijkstra,Dijkstra(最小费用最大流)
裸的费用流.往返就相当于从起点走两条路到终点. 按题意建图,将距离设为费用,流量设为1.然后增加2个点,一个连向节点1,流量=2,费用=0;结点n连一条同样的弧,然后求解最小费用最大流.当且仅当最大流 ...
- TZOJ 1513 Farm Tour(最小费用最大流)
描述 When FJ's friends visit him on the farm, he likes to show them around. His farm comprises N (1 &l ...
- POJ 2135 Farm Tour (网络流,最小费用最大流)
POJ 2135 Farm Tour (网络流,最小费用最大流) Description When FJ's friends visit him on the farm, he likes to sh ...
- POJ 2135 Farm Tour(最小费用最大流)
Description When FJ's friends visit him on the farm, he likes to show them around. His farm comprise ...
随机推荐
- ♫【模式】Curry化
/** * 当发现正在调用同一个函数,并且传递的参数绝大多数都是相同的, * 那么该函数可能是用于Curry化的一个很好的候选参数 */ ;(function() { function add(x, ...
- bzoj 2819 Nim(BIT,dfs序,LCA)
2819: Nim Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1596 Solved: 597[Submit][Status][Discuss] ...
- HDU 2089 不要62(挖个坑=-=)
不要62 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- asp 数组
定义简单数组 有两种方法在asp中定义和初始化数组,让我们看看每种的例子: 方法一:MyArray = Array("Jan","Feb","Mar& ...
- octopress添加回到顶部按钮
准备回到顶部的png图片一枚,可以随自己喜好google.分享我的 取名top.png,保存在octopress/source/images/top.png octopress/source/_inc ...
- Python切割nginx日志_小组_ThinkSAAS
Python切割nginx日志_小组_ThinkSAAS Python切割nginx日志
- 最全面的 DNS 原理入门
DNS 是互联网核心协议之一.不管是上网浏览,还是编程开发,都需要了解一点它的知识. 本文详细介绍DNS的原理,以及如何运用工具软件观察它的运作.我的目标是,读完此文后,你就能完全理解DNS. 一.D ...
- poj 2367 Genealogical tree【拓扑排序输出可行解】
Genealogical tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3674 Accepted: 2445 ...
- 我眼中的 Oracle 性能优化
恒生技术之眼 作者 林景忠 大家对于一个业务系统的运行关心有如下几个方面:功能性.稳定性.效率.安全性.而一个系统的性能有包含了网络性能.应用性能.中间件性能.数据库性能等等. 今天从数据库性能的角度 ...
- 让python输出不自行换行的方法
1,在输出内容后加逗号 例: for i in range(1,6): j = 1 while(j <= 2*i - 1): print "*", ...