题目大意

一个图上有N个顶点,从1到N标号,顶点之间存在一些无向边,边有长度,要求从顶点1走到顶点N,再从顶点N走回顶点1,其中不必要经过每个顶点,但是要求走的路径上的边只能经过一次。求出从1--->N-->1的路径的长度最小值。

题目分析

每条无向边最多只能走一次,可以视为这些边的容量只有1。题目中要求从顶点1走到N再走回顶点1,其中经过的边只能走一次,其实可以看做从顶点1出发的两条不同的路径(路径的边不能有重合)到达顶点N。那么就可以视为,从顶点1出发到达顶点N的总流量为2. 题目要求总路径长度最小值,可以将路径长度视为网络流费用,则问题转化为求解最小费用最大流。 
    引入源点ss和汇点tt,ss引入一条边到顶点1,容量为2,费用为0;从顶点N引入一条边到tt,容量为2,费用为0。则问题就成了求从ss出发到达tt的最小费用最大流。 
    由于边为无向边,因此在添加边的时候,u-->v和v-->u都要添加,且添加相应的反向边(即实际图中(u,v)边在网络流图中上有4条边对应)。

实现(c++)

#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
#define INFINITE 1 << 26
#define MAX_NODE 1005
#define MAX_EDGE_NUM 40005
struct Edge{
int to;
int vol;
int cost;
int next;
};
Edge gEdges[MAX_EDGE_NUM]; int gHead[MAX_NODE];
int gPre[MAX_NODE];
int gPath[MAX_NODE];
int gDist[MAX_NODE]; int gEdgeCount;
void InsertEdge(int u, int v, int vol, int cost){
gEdges[gEdgeCount].to = v;
gEdges[gEdgeCount].vol = vol;
gEdges[gEdgeCount].cost = cost;
gEdges[gEdgeCount].next = gHead[u];
gHead[u] = gEdgeCount++; gEdges[gEdgeCount].to = u;
gEdges[gEdgeCount].vol = 0; //vol为0,表示开始时候,该边的反向不通
gEdges[gEdgeCount].cost = -cost; //cost 为正向边的cost相反数,这是为了
gEdges[gEdgeCount].next = gHead[v];
gHead[v] = gEdgeCount++;
} //假设图中不存在负权和环,SPFA算法找到最短路径/从源点s到终点t所经过边的cost之和最小的路径
bool Spfa(int s, int t){
memset(gPre, -1, sizeof(gPre));
memset(gDist, 0x7F, sizeof(gDist));
gDist[s] = 0;
queue<int> Q;
Q.push(s);
while (!Q.empty()){//由于不存在负权和环,因此一定会结束
int u = Q.front();
Q.pop(); for (int e = gHead[u]; e != -1; e = gEdges[e].next){
int v = gEdges[e].to;
if (gEdges[e].vol > 0 && gDist[u] + gEdges[e].cost < gDist[v]){
gDist[v] = gDist[u] + gEdges[e].cost;
gPre[v] = u; //前一个点
gPath[v] = e;//该点连接的前一个边
Q.push(v);
}
}
} if (gPre[t] == -1) //若终点t没有设置pre,说明不存在到达终点t的路径
return false;
return true;
} int MinCostFlow(int s, int t){
int cost = 0;
int flow = 0;
while (Spfa(s, t)){
int f = INFINITE;
for (int u = t; u != s; u = gPre[u]){
if (gEdges[gPath[u]].vol < f)
f = gEdges[gPath[u]].vol;
}
flow += f;
cost += gDist[t] * f;
for (int u = t; u != s; u = gPre[u]){
gEdges[gPath[u]].vol -= f; //正向边容量减少
gEdges[gPath[u]^1].vol += f; //反向边容量增加
}
}
return cost;
}
int main(){
int n, m, u, v, d;
while (scanf("%d %d", &n, &m) != EOF){
gEdgeCount = 0;
memset(gHead, -1, sizeof(gHead));
InsertEdge(0, 1, 2, 0);
for (int i = 0; i < m; i++){
scanf("%d %d %d", &u, &v, &d);
InsertEdge(u, v, 1, d);
InsertEdge(v, u, 1, d);
}
InsertEdge(n, n + 1, 2, 0); int ans = MinCostFlow(0, n + 1);
printf("%d\n", ans);
}
return 0;
}

poj_2315 最小费用最大流的更多相关文章

  1. [板子]最小费用最大流(Dijkstra增广)

    最小费用最大流板子,没有压行.利用重标号让边权非负,用Dijkstra进行增广,在理论和实际上都比SPFA增广快得多.教程略去.转载请随意. #include <cstdio> #incl ...

  2. bzoj1927最小费用最大流

    其实本来打算做最小费用最大流的题目前先来点模板题的,,,结果看到这道题二话不说(之前打太多了)敲了一个dinic,快写完了发现不对 我当时就这表情→   =_=你TM逗我 刚要删突然感觉dinic的模 ...

  3. ACM/ICPC 之 卡卡的矩阵旅行-最小费用最大流(可做模板)(POJ3422)

    将每个点拆分成原点A与伪点B,A->B有两条单向路(邻接表实现时需要建立一条反向的空边,并保证环路费用和为0),一条残留容量为1,费用为本身的负值(便于计算最短路),另一条残留容量+∞,费用为0 ...

  4. HDU5900 QSC and Master(区间DP + 最小费用最大流)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5900 Description Every school has some legends, ...

  5. P3381 【模板】最小费用最大流

    P3381 [模板]最小费用最大流 题目描述 如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用. 输入输出格式 输入格式: 第一行 ...

  6. 【BZOJ-3876】支线剧情 有上下界的网络流(有下界有源有汇最小费用最大流)

    3876: [Ahoi2014]支线剧情 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 821  Solved: 502[Submit][Status ...

  7. hdu 4411 2012杭州赛区网络赛 最小费用最大流 ***

    题意: 有 n+1 个城市编号 0..n,有 m 条无向边,在 0 城市有个警察总部,最多可以派出 k 个逮捕队伍,在1..n 每个城市有一个犯罪团伙,          每个逮捕队伍在每个城市可以选 ...

  8. UVa11082 Matrix Decompressing(最小费用最大流)

    题目大概有一个n*m的矩阵,已知各行所有数的和的前缀和和各列所有数的和的前缀和,且矩阵各个数都在1到20的范围内,求该矩阵的一个可能的情况. POJ2396的弱化版本吧..建图的关键在于: 把行.列看 ...

  9. UVa12092 Paint the Roads(最小费用最大流)

    题目大概说一个n个点m条带权有向边的图,要给边染色,染色的边形成若干个回路且每个点都恰好属于其中k个回路.问最少要染多少边权和的路. 一个回路里面各个点的入度=出度=1,那么可以猜想知道各个点如果都恰 ...

随机推荐

  1. shell中执行hive命令错误:delimited by end-of-file (wanted `EOF')

    错误信息: warning: here-document at line 58 delimited by end-of-file (wanted `EOF') 业务场景,使用hive对数据进行批量清洗 ...

  2. shell脚本----if(数字条件,字符串条件,字符串为空)

    二元比较操作符,比较变量或者比较数字. 注意数字与字符串的区别. 1.整数比较  -eq 等于,如:if [ "$a" -eq "$b" ] -ne 不等于,如 ...

  3. Android APP 分享图片文字到微信刚開始正常,后面就不弹出分享框了

    依照官方的流程走了一遍.一切顺利,分享成功了.本来以为能够大功告成了,结果睡了一觉,第二天要给客户演示了.才发现TMD坑爹了,不能分享了,第三方的分享栏弹不出来了.我一阵惊慌,还好非常快找到了解决的方 ...

  4. IE6、IE7、IE8、Firefox兼容性

    整理关于IE6.IE7.IE8.Firefox兼容性CSS HACK问题 1.区别IE和非IE浏览器CSS HACK代码 #divcss5{background:blue; /*非IE 背景藍色*/b ...

  5. [oracle] oracle权限传递

    三个用户:SYS.lisi.wangwu ① 系统权限的传递 lisi的初始化系统权限 SQL> select * from user_sys_privs; USERNAME PRIVILEGE ...

  6. RunnableException与CheckedException

    Checked Exception 编译时异常 编译的时候检查你的代码可能在运行的时候抛出异常,这通常在编译的时候要去处理的. RunnableException 运行时异常,可以编译通过,但如果不处 ...

  7. REFLECTOR和FILEDISASSEMBLER的下载与使用

    .NET Reflector 下载地址 http://www.aisto.com/roeder/dotnet FileDisassembler 下载地址 http://www.denisbauer.c ...

  8. Eclipse/MyEclipse全屏插件

    此插件可以让Eclipse/MyEclipse的界面全屏,隐藏菜单栏和状态栏! MyEclipse 2014/2015中亲测有效! 插件下载: http://files.cnblogs.com/got ...

  9. Jquery实现选项卡功能

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. R语言低级绘图函数-symbols

    严格意义上将symbols 并不能算是一个低级的绘图函数,因为它不仅可以在一幅已经存在的图标上添加元素,还可以创建一张新的图表 鉴于它绘图时的灵活性,我把它归入到低级绘图函数中 symbols 可以创 ...