题目大意

一个图上有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. Eclipse 中 Debug 模式跳转到 exitCurrentThread 的问题解决

    问题描述: Debug 模式启动项目,断点跳转到exitCurrentThread 解决方法: 修改Eclipse 配置 [window]->[Preferences]->[Java]-& ...

  2. 6. GC 调优(工具篇) - GC參考手冊

    进行GC性能调优时, 须要明白了解, 当前的GC行为对系统和用户有多大的影响. 有多种监控GC的工具和方法, 本章将逐一介绍经常使用的工具. 您应该已经阅读了前面的章节: 垃圾收集简单介绍 - GC參 ...

  3. js元素绑定事件

    想给一个元素绑定一个方法之后,在绑定一个方法而且不被覆盖 window.onload = function () { alert('a'); } window.onlaod=function(){ a ...

  4. 周末大礼:jQuery技巧总结

    一.简介 1.1.概述 随着WEB2.0及ajax思想在互联网上的快速发展传播,陆续出现了一些优秀的Js框架,其中比较著名的有Prototype.YUI.jQuery.mootools.Bindows ...

  5. VMWare 回收磁盘空间

    两部分内容: 1) 实际操作体验下在vmware player里回收guest vm的磁盘空间,还给host: 2)顺便把之前的笔记翻出来关于vmware unmap/reclaim, 对照总结. 1 ...

  6. 转载:erlang程序优化点的总结

    erlang程序优化点的总结(持续更新) 转自:http://wqtn22.iteye.com/blog/1820587 转载请注明出处 注意,这里只是给出一个总结,具体性能需要根据实际环境和需要来确 ...

  7. Ubuntu 14.04 安装R 环境

    Introduction R is a popular open source programming language that specializes in statistical computi ...

  8. 【Java面试题】7 构造器Constructor是否可被override?

    构造器Constructor不能被继承,因此不能重写Override,但可以被重载Overload. Constructor不能被继承,所以Constructor也就不能被override.每一个类必 ...

  9. jquery-创建元素和添加子元素

    一.创建新元素 1.使用$函数创建新元素 var $newElement=$('<div><p>段落</p></div>');//创建元素,返回jQue ...

  10. 微软ASP.NET网站部署指南(2):部署SQL Server Compact数据库

    1. 综述 对于数据库訪问,Contoso University程序要求以下的软件必须随程序一起部署.由于不属于.NET Framework: SQL Server Compact (数据库引擎) A ...