题目大意

一个图上有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. 透明遮罩图层VS高斯模糊滤镜 效果分析

    前端流行布局中最常见的弹出图层有popup, 对话框, tooltip等, 他们都使用了新的图层,但是实现办法各不相同, 有 的是通过半通明的黑白图层实现的, 有的是通过滤镜实现的, 我们来研究一下两 ...

  2. Mac下删除安装的pkg

        Mac下的安装和删除都比windows更加简单清晰,这点在dmg方式下非常明显,但很多时候我们会使用pkg来进行安装,这样的安装想删除就有点麻烦了. 比如,我安装了Golang这个pkg用于g ...

  3. mysql pdo事务

    /* 开始一个事务,关闭自动提交 */直到调用commit结束事务时才提交 $dbh->beginTransaction(); bool PDO::commit ( void ) 提交一个事务, ...

  4. HTTP API 设计指南(基础部分)

    前言 这篇指南介绍描述了 HTTP+JSON API 的一种设计模式,最初摘录整理自 Heroku 平台的 API 设计指引 Heroku 平台 API 指引. 这篇指南除了详细介绍现有的 API 外 ...

  5. js学习笔记21----表格操作

    1.获取表格元素: tHead : 表格头 tBody : 表格主体内容 tFoot : 表格尾 rows  : 表格行 cells  : 表格列 如获取表格第一行第一列的数据: <script ...

  6. js匹配浏览器类型,收藏下

    <script type="text/javascript">/** 智能机浏览器版本信息:**/  varbrowser={    versions:function ...

  7. 文本处理三剑客之AWK的用法

    1.awk命令简介: awk是一种可以处理数据.产生格式化报表的语言,功能十分强大. awk的工作方式是读取数据,将每一行数据视为一条记录(record)每笔记录以字段分隔符分成若干字段,然后输出各个 ...

  8. 最短路径问题-Floyd算法

    概念 最短路径也是图的一个应用,即寻找图中某两个顶点的最短路径长度. 实际应用:例如确定某两个城市间的坐火车最短行车路线长度等. Floyd algorithm 中文名就是弗洛伊德算法. 算法思路:用 ...

  9. mysql 5.7 详细图文安装教程

    官网下载太慢,可以上下载频道下载(mysql-installer-community-5.7.13.0.msi): http://download.csdn.net/download/tan3739/ ...

  10. Oracle RAC:使用 NFS 共享存储时的 mount 选项 总结

    oracle rac 使用nfs作为共享存储时,mount的选项有 要求,不能随便设置 grid的要求:      rw,bg,hard,nointr,rsize=32768,wsize=32768, ...