POJ 2135 Farm Tour (网络流,最小费用最大流)

Description

When FJ's friends visit him on the farm, he likes to show them around. His farm comprises N (1 <= N <= 1000) fields numbered 1..N, the first of which contains his house and the Nth of which contains the big barn. A total M (1 <= M <= 10000) paths that connect the fields in various ways. Each path connects two different fields and has a nonzero length smaller than 35,000.

To show off his farm in the best way, he walks a tour that starts at his house, potentially travels through some fields, and ends at the barn. Later, he returns (potentially through some fields) back to his house again.

He wants his tour to be as short as possible, however he doesn't want to walk on any given path more than once. Calculate the shortest tour possible. FJ is sure that some tour exists for any given farm.

Input

Line 1: Two space-separated integers: N and M.

Lines 2..M+1: Three space-separated integers that define a path: The starting field, the end field, and the path's length.

Output

A single line containing the length of the shortest tour.

Sample Input

4 5

1 2 1

2 3 1

3 4 1

1 3 2

2 4 2

Sample Output

6

Http

POJ:https://vjudge.net/problem/POJ-2135

Source

图论,网络流,最小费用最大流

题目大意

给定一个n个点m条边的无向图,求两条不相交的从1到n的最短路径。

解决思路

看到这道题目时,首先想到的是最短路径的算法,但显然不是跑两边Dijkstra或spfa,想要两条路一起走也不科学,所以我们想到了网络流算法。

想一想,我们要求两条不相交的从1到n的最短路径,若假设我们把所有的边看作流量为1的边,那么这是不是要求从1到n容量为2的流呢?所以我们可以想到有如下的算法:

对于原来的边上的权值“距离”,我们将其换一个定义:花费。另外再给每一个边赋上1的流量。同时,为了控制1点流出的和n点汇入的流不超过2,我们再设一个超级源点和超级汇点,在超级源点与1之间连流量为2的边,而在n与超级汇点之间连流量为2的边。然后,我们就可以用最小费用最大流来解决了。

需要注意的是,这道题目的边是无向边,所以我们在网络流连边时也要连无向边,所以本题不能用邻接矩阵来存图,而要使用邻接表的形式

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std; const int maxN=5001;
const int maxM=50001;
const int inf=2147483647; class Edge
{
public:
int u,v,flow,cost;//记录每一条边的信息,出点,目的点,残量,花费
}; int n,m;
int cnt=-1;//记录邻接表的边数
int Head[maxN];
int Next[maxM];
Edge E[maxM];
int Flow[maxN];//spfa中保存每个点可以通过的残量
int Pre[maxN];//spfa中保存每个点是由哪一条边转移过来的边的标号
int Dist[maxN];//spfa中保存到每个点的距离,即最小花费
bool inqueue[maxN]; void Add_Edge(int u,int v,int flow,int cost);//添加边
void _Add(int u,int v,int flow,int cost);
bool spfa(); int main()
{
cin>>n>>m;
memset(Head,-1,sizeof(Head));
memset(Next,-1,sizeof(Next));
for (int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
Add_Edge(u,v,1,w);//注意,正反边都要连
Add_Edge(v,u,1,w);
}
Add_Edge(0,1,2,0);//连接源点与1
Add_Edge(n,n+1,2,0);//连接n与汇点
int Ans=0;//记录花费
while (spfa())//spfa寻增广路
{
int now=n+1;
int last=Pre[now];//从汇点向回走,将增广路上的每一条边均减去消耗的流量
while (now!=0)
{
E[last].flow-=Flow[n+1];
E[last^1].flow+=Flow[n+1];
now=E[last].u;
last=Pre[now];
}
Ans+=Dist[n+1]*Flow[n+1];//累计花费
}
cout<<Ans<<endl;
} void Add_Edge(int u,int v,int flow,int cost)
{
_Add(u,v,flow,cost);//每一次加边的同时,加入其反向边,反向边的残量为0,花费为-cost
_Add(v,u,0,-cost);
return;
} void _Add(int u,int v,int flow,int cost)
{
cnt++;
Next[cnt]=Head[u];
Head[u]=cnt;
E[cnt].u=u;
E[cnt].v=v;
E[cnt].flow=flow;
E[cnt].cost=cost;
return;
} bool spfa()
{
memset(Pre,-1,sizeof(Pre));//前驱边的编号
memset(inqueue,0,sizeof(inqueue));
memset(Flow,0,sizeof(Flow));
memset(Dist,127,sizeof(Dist));
queue<int> Q;
while (!Q.empty())
Q.pop();
Q.push(0);//将源点放入队列
Dist[0]=0;
Flow[0]=inf;
inqueue[0]=1;
do
{
int u=Q.front();
//cout<<u<<endl;
inqueue[u]=0;
Q.pop();
for (int i=Head[u];i!=-1;i=Next[i])
{
int v=E[i].v;
if ((E[i].flow>0)&&(Dist[u]+E[i].cost<Dist[v]))//当还有残量存在且花费更小时,修改v的信息
{
Dist[v]=E[i].cost+Dist[u];
Pre[v]=i;
Flow[v]=min(Flow[u],E[i].flow);
if (inqueue[v]==0)
{
Q.push(v);
inqueue[v]=1;
}
}
}
}
while (!Q.empty());
if (Pre[n+1]==-1)//当汇点没有前驱,及说明没有增广到汇点,也说明不存在增广路,直接退出
return 0;
return 1;
}

POJ 2135 Farm Tour (网络流,最小费用最大流)的更多相关文章

  1. POJ 2135 Farm Tour (最小费用最大流模板)

    题目大意: 给你一个n个农场,有m条道路,起点是1号农场,终点是n号农场,现在要求从1走到n,再从n走到1,要求不走重复路径,求最短路径长度. 算法讨论: 最小费用最大流.我们可以这样建模:既然要求不 ...

  2. POJ 2135 Farm Tour(最小费用最大流)

    Description When FJ's friends visit him on the farm, he likes to show them around. His farm comprise ...

  3. POJ 2135 Farm Tour(最小费用最大流,变形)

    题意:给一个无向图,FJ要从1号点出发到达n号点,再返回到1号点,但是路一旦走过了就会销毁(即回去不能经过),每条路长度不同,那么完成这趟旅行要走多长的路?(注:会有重边,点号无序,无向图!) 思路: ...

  4. poj 2135 Farm Tour【 最小费用最大流 】

    第一道费用流的题目--- 其实---还是不是很懂,只知道沿着最短路找增广路 建图 源点到1连一条容量为2(因为要来回),费用为0的边 n到汇点连一条容量为2,费用为0的边 另外的就是题目中输入的了 另 ...

  5. Minimum Cost 【POJ - 2516】【网络流最小费用最大流】

    题目链接 题意: 有N个商家它们需要货物源,还有M个货物供应商,N个商家需要K种物品,每种物品都有对应的需求量,M个商家每种物品都是对应的存货,然后再是K个N*M的矩阵表示了K个物品从供货商运送到商家 ...

  6. POJ2135 Farm Tour(最小费用最大流)

    题目问的是从1到n再回到1边不重复走的最短路,本质是找1到n的两条路径不重复的尽量短的路. #include<cstdio> #include<cstring> #includ ...

  7. poj 2135 Farm Tour 【无向图最小费用最大流】

    题目:id=2135" target="_blank">poj 2135 Farm Tour 题意:给出一个无向图,问从 1 点到 n 点然后又回到一点总共的最短路 ...

  8. 网络流(最小费用最大流):POJ 2135 Farm Tour

    Farm Tour Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: ...

  9. POJ 2135.Farm Tour 消负圈法最小费用最大流

    Evacuation Plan Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4914   Accepted: 1284   ...

随机推荐

  1. Oracle-归档日志详解(运行模式、分类)

    一.Oracle日志分类 分三大类: Alert log files--警报日志,Trace files--跟踪日志(用户和进程)和            redo log 重做日志(记录数据库的更改 ...

  2. 全虚拟化和半虚拟化的区别 cpu的ring0 ring1又是什么概念? - 转

    http://www.cnblogs.com/xusongwei/archive/2012/07/30/2615592.html ring0是指CPU的运行级别,ring0是最高级别,ring1次之, ...

  3. CF 55 D. Beautiful numbers

    D. Beautiful numbers 链接 题意: 求[L,R]中多少个数字可以整除它们的每一位上的数字. 分析: 要求模一些数字等于0等价于模它们的lcm等于0,所以可以记录当前出现的数字的lc ...

  4. 第二十九章 springboot + zipkin + mysql

    zipkin的数据存储可以存在4个地方: 内存(仅用于测试,数据不会持久化,zipkin-server关掉,数据就没有了) 这也是之前使用的 mysql 可能是最熟悉的方式 es Cassandra ...

  5. Unity关于方法事件生命周期官方文档

    http://docs.unity3d.com/Manual/ExecutionOrder.html 一.组件运行的基本顺序 下图中创建类的顺序为A,B,C,A1,二运行的结果为A1,B,C,A. 可 ...

  6. Laya鼠标事件阅读

    点击事件核心类:MouseManager和TouchManager. MouseManager负责收集相关事件,进行捕获阶段和目标阶段. TouchManger负责处理和分发事件,进行冒泡阶段. 捕获 ...

  7. Verilog HDL数组(存储器)操作

    本文从本人的163博客搬迁至此. 引用了http://blog.sina.com.cn/s/blog_9424755f0101rhrh.html Verilog HDL中常采用数组方式来对存储器进行建 ...

  8. Ubuntu 18.04下Couldn't connect to Docker daemon at http+docker://localunixsocket解决办法

    一台服务器系统为:Ubuntu 18.04 LTS,上面建了git裸仓库,用于开发吧代码push到这里.同时WEB测试环境通过docker也部署在这台.通过git钩子post-receive,当有新代 ...

  9. LeetCode-51.N皇后

    n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 上图为 8 皇后问题的一种解法. 给定一个整数 n,返回所有不同的 n 皇后问题的解决方案. 每一种解 ...

  10. Daily Scrumming* 2015.12.11(Day 3)

    一.团队scrum meeting照片 二.今日总结 姓名 WorkItem ID 工作内容 签入链接以及备注说明  江昊 任务945 学习使用sass,学习的主要难点在于ruby环境的搭建.sass ...