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 ...
随机推荐
- (转载)浅谈javascript的分号
(转载)http://www.blueidea.com/tech/web/2009/7261.asp javascript的分号代表语句的结束符,但由于javascript具有分号自动插入规则,所以它 ...
- HDU 5914 Triangle 【构造】 (2016中国大学生程序设计竞赛(长春))
Triangle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
- MyEclipse Spring被删之后,如何在myeclipse里面重新导入
1.找到项目文件 2.用记事本打开 .project 把里面涉及到spring的全部删除就可以了.
- lazyman学习
1.安装: gem install lazyman 2.建立工程: cd到工程目录下 lazyman new 工程名 3.打开调试命令 lazyman c lazyman调用selenium-webd ...
- [Linux&Vim]基础01
学习和使用Linux有一段时间了,作为这么长时间的学习应该是有一定收获的,可惜的是没有一股专研精神,只停留在皮毛. 阅读过一些大牛们学习Linux和Vim的过程,从命令.环境配置.使用个性化设置.编程 ...
- Eclipse添加快速查找Dao中方法所对应的Mybatis XML映射SQL的插件
Dao关联Mybatis快速查找的插件安装地址:http://dl.bintray.com/harawata/eclipse 安装步骤: ①Eclipse ==> Help ==> Ins ...
- Android学习笔记(四)深入探讨Activity
在应用程序中至少包含一个用来处理应用程序的主UI功能的主界面屏幕.这个主界面一般由多个Fragment组成,并由一组次要Activity支持.要在屏幕之间切换,就必须要启动一个新的Activity.一 ...
- hdoj 1384 Intervals
Intervals Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- hdoj 2187 悼念512汶川大地震遇难同胞——老人是真饿了【贪心部分背包】
悼念512汶川大地震遇难同胞——老人是真饿了 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- HDU 4432 Sum of divisors (进制模拟)
三个小函数 getdiv(); 求因子 getsum(); 求平方和 change(); 转换成该进制 #include <cstdio> #include ...