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 ...
随机推荐
- -_-#【HTML】同一个标签页打开
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- Kafka Topic Partition Replica Assignment实现原理及资源隔离方案
本文共分为三个部分: Kafka Topic创建方式 Kafka Topic Partitions Assignment实现原理 Kafka资源隔离方案 1. Kafka Topic创建方式 ...
- Spark使用CombineTextInputFormat缓解小文件过多导致Task数目过多的问题
目前平台使用Kafka + Flume的方式进行实时数据接入,Kafka中的数据由业务方负责写入,这些数据一部分由Spark Streaming进行流式计算:另一部分数据则经由Flume存储至HDFS ...
- (转载)ubuntu安装pyton-pip问题解决
一.问题描述 root@ubuntu:/home/chao# apt-get install python-pip 正在读取软件包列表... 完成 正在分析软件包的依赖关系树 正在读取状态信息... ...
- 文件夹oradiag_是如何产生的
如果sqlnet.ora不可用或者ADR_BASE参数未定义,那么11g的 SQL*Net将创建这些文件夹 (详情:http://download.oracle.com/docs/cd/B28359_ ...
- Erasing Edges - SGU 136(构造多边形)
题目大意:已知一个多边形上的每条边的中点,还原出来一个多边形. 分析:因为偶数是不固定的,所以可以为任意起点,奇数只有一个,可以所有中点加减算出来第一个点,然后就是简单的向量计算点的位置了...... ...
- selenium.common.exceptions.TimeoutException: Message: Screenshot: available via screen
在使用selenium+phantomjs的时候在Windows平台下能够正常工作,在Linux下却不能,并得到错误信息: selenium.common.exceptions.TimeoutExce ...
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(27)-权限管理系统-分配用户给角色
原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(27)-权限管理系统-分配用户给角色 分配用户给角色,跟分配角色给用户操作是基本一致的. 打开模块维护,展 ...
- 摄像头参数查看与调节 分类: C/C++ OpenCV 2014-11-08 18:13 138人阅读 评论(0) 收藏
cvGetCaptureProperty 获得视频获取结构的属性 double cvGetCaptureProperty( CvCapture* capture, int property_id ); ...
- wdlinux mysql innodb的安装
mysql innodb的安装 wget -c http://down.wdlinux.cn/in/mysql_innodb_ins.sh chmod 755 mysql_innodb_ins.sh ...