POJ 2135 Farm Tour (网络流,最小费用最大流)
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 (网络流,最小费用最大流)的更多相关文章
- POJ 2135 Farm Tour (最小费用最大流模板)
题目大意: 给你一个n个农场,有m条道路,起点是1号农场,终点是n号农场,现在要求从1走到n,再从n走到1,要求不走重复路径,求最短路径长度. 算法讨论: 最小费用最大流.我们可以这样建模:既然要求不 ...
- POJ 2135 Farm Tour(最小费用最大流)
Description When FJ's friends visit him on the farm, he likes to show them around. His farm comprise ...
- POJ 2135 Farm Tour(最小费用最大流,变形)
题意:给一个无向图,FJ要从1号点出发到达n号点,再返回到1号点,但是路一旦走过了就会销毁(即回去不能经过),每条路长度不同,那么完成这趟旅行要走多长的路?(注:会有重边,点号无序,无向图!) 思路: ...
- poj 2135 Farm Tour【 最小费用最大流 】
第一道费用流的题目--- 其实---还是不是很懂,只知道沿着最短路找增广路 建图 源点到1连一条容量为2(因为要来回),费用为0的边 n到汇点连一条容量为2,费用为0的边 另外的就是题目中输入的了 另 ...
- Minimum Cost 【POJ - 2516】【网络流最小费用最大流】
题目链接 题意: 有N个商家它们需要货物源,还有M个货物供应商,N个商家需要K种物品,每种物品都有对应的需求量,M个商家每种物品都是对应的存货,然后再是K个N*M的矩阵表示了K个物品从供货商运送到商家 ...
- POJ2135 Farm Tour(最小费用最大流)
题目问的是从1到n再回到1边不重复走的最短路,本质是找1到n的两条路径不重复的尽量短的路. #include<cstdio> #include<cstring> #includ ...
- poj 2135 Farm Tour 【无向图最小费用最大流】
题目:id=2135" target="_blank">poj 2135 Farm Tour 题意:给出一个无向图,问从 1 点到 n 点然后又回到一点总共的最短路 ...
- 网络流(最小费用最大流):POJ 2135 Farm Tour
Farm Tour Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: ...
- POJ 2135.Farm Tour 消负圈法最小费用最大流
Evacuation Plan Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4914 Accepted: 1284 ...
随机推荐
- Getting Start chrome-extension demo
写一个小小的chrome扩展demo~ 准备工作 了解一下插件chrome-extension: 在应用商店里的插件基本上都是以.crx为文件后缀,该文件其实就是一个压缩包,包括插件所需要的html. ...
- Luogu P2577 [ZJOI2005]午餐
一道贪心+类背包DP的好题 首先发现一个十分显然的性质,没有这个性质整道题目都难以下手: 无论两队的顺序如何,总是让吃饭慢的人先排队 这是一个很显然的贪心,因为如果让吃饭慢的排在后面要更多的时间至少没 ...
- 备忘:BLOCK CORRUPTION IN SYSTEM DATAFILE
http://www.onlinedbasupport.com/2010/12/10/block-corruption-in-system-datafile/
- 本地navicat远程连接到云服务器数据库
本来没有开启秘钥的远程服务器端数据库连接非常方便,就在新建连接上填入数据就ok了,但是开启SSH秘钥后的服务器连接有一个大坑,下面来详细讲讲. 其实开启了秘钥,在新建连接下,先选择SSH方式登录到远程 ...
- REST-framework快速构建API--初体验
一.快速上手 1.环境准备 安装restframework,注册app pip install djangorestframework INSTALLED_APPS = [ 'django.contr ...
- java十年,需要学会的Java开发体系
阿里十年,只剩下这套Java开发体系了,链接:https://www.jianshu.com/p/ca6c4a73aac9
- Jmeter(八)-发送JDBC请求
下午花了两个小时研究了一下Jmeter发送JDBC请求,现在把基本操作流程分享一下. 做JDBC请求,首先需要两个jar包:mysql驱动-mysql-connector-java-5.1.13-bi ...
- Frida----安装
介绍 它是本机应用程序的 Greasemonkey,或者更多技术术语,它是一个动态代码检测工具包.它允许您将JavaScript或您自己的库的片段注入Windows,macOS,GNU / Linux ...
- 微软职位内部推荐-Principal Software Eng Mgr
微软近期Open的职位: Job Title:   Principal Software Eng Mgr Work Location: Shanghai, China Job Desc ...
- PHP学习 Object Oriented 面向对象 OO
定义类class class_name [extends partclass_name]{public private protected var property_name = value;publ ...