POJ2135 Farm Tour 最小费用流

给出一个图,从一号节点去N号节点,再回来。

但是不能经过相同的边,即一条边最多只能够走一次。

求来回的总长度的最小值。

转化:

求1号到N号的2条没有公共边的路径,这样就相当于在这个图中所有边的容量都是1,现在要找2条增广路,得到的流量为2,就相当于求流量为2的最小费用流。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 #include<vector>
  5
  6 using namespace std;
  7
  8 const int maxn=1005;
  9 const int inf=0x3f3f3f3f;
 10 const int s=1;
 11 int t;
 12
 13 inline int min(int x,int y)
 14 {
 15     return x<y?x:y;
 16 }
 17
 18 struct Edge
 19 {
 20     int to,cap,cost,rev;
 21 };
 22 vector<Edge>edge[maxn];
 23 int prev[maxn];
 24 int pree[maxn];
 25 int dist[maxn];
 26 int vis[maxn];
 27
 28 void addedge(int from,int to,int cap,int cost)
 29 {
 30     edge[from].push_back((Edge){to,cap,cost,edge[to].size()});
 31     edge[to].push_back((Edge){from,0,-cost,edge[from].size()-1});
 32 }
 33
 34 void build_graph(int n,int m)
 35 {
 36     t=n;
 37     for(int i=1;i<=m;i++)
 38     {
 39         int u,v,w;
 40         scanf("%d%d%d",&u,&v,&w);
 41         addedge(u,v,1,w);
 42         addedge(v,u,1,w);
 43     }
 44 }
 45
 46 void spfa(int n)
 47 {
 48     memset(vis,false,sizeof vis);
 49     for(int i=2;i<=n;i++)
 50         dist[i]=inf;
 51     dist[1]=0;
 52     queue<int>que;
 53     while(!que.empty())
 54         que.pop();
 55     que.push(s);
 56     vis[s]=true;
 57     while(!que.empty())
 58     {
 59         int u=que.front();
 60         que.pop();
 61         vis[u]=false;
 62         for(int i=0;i<edge[u].size();i++)
 63         {
 64             Edge &e=edge[u][i];
 65             if(e.cap>0&&dist[e.to]>dist[u]+e.cost)
 66             {
 67                 dist[e.to]=dist[u]+e.cost;
 68                 prev[e.to]=u;
 69                 pree[e.to]=i;
 70                 if(!vis[e.to])
 71                 {
 72                     que.push(e.to);
 73                     vis[e.to]=true;
 74                 }
 75             }
 76         }
 77     }
 78 }
 79
 80 int min_cost_flow(int f,int n)
 81 {
 82     int ret=0;
 83     while(f>0)
 84     {
 85         spfa(n);
 86         int d=f;
 87         for(int v=t;v!=s;v=prev[v])
 88         {
 89             d=min(d,edge[prev[v]][pree[v]].cap);
 90         }
 91         f-=d;
 92         ret+=dist[t]*d;
 93         for(int v=t;v!=s;v=prev[v])
 94         {
 95             Edge &e=edge[prev[v]][pree[v]];
 96             e.cap-=d;
 97             edge[e.to][e.rev].cap+=d;
 98         }
 99     }
100     return ret;
101 }
102
103 int main()
104 {
105     int n,m;
106     while(~scanf("%d%d",&n,&m))
107     {
108         build_graph(n,m);
109
110         printf("%d\n",min_cost_flow(2,n));
111     }
112     return 0;
113 }

时间: 2024-10-03 23:10:06

POJ2135 Farm Tour 最小费用流的相关文章

解题报告 之 POJ2135 Farm Tour

解题报告 之 POJ2135 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.

POJ 2135.Farm Tour 最小费用流

Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17307   Accepted: 6687 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

POJ2135 Farm Tour 【最小费用最大流】

Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11782   Accepted: 4393 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

poj 2135 Farm Tour 最小费用流入门模板

题意: 求点1到点n再从点n回点1不经过同一条路的最短路. 分析: 建图容易,给一组针对求两次最短路的数据: 4 5 1 2 1 1 3 100 2 4 100 2 3 1 3 4 1 接下来上最小费用流的模板就好. 代码: //poj 2135 //sep9 #include <iostream> #include <queue> using namespace std; const int maxN=2048; const int maxM=20024; struct Edge

【网络流#9】POJ 2135 Farm Tour 最小费用流 - 《挑战程序设计竞赛》例题

[题意]给出一张无向图,从1开始到n,求两条没有公共边的最短路,使得路程总和最小 每条边的权值设为费用,最大流量设为1,然后就是从源点到汇点流量为2的最小费用流. 因为是规定了流量,新建一个源点和一个汇点,源点到结点1连一条最大流量为2,费用为0的边,结点N到汇点连一条最大流量为2,费用为0的边,这样就规定好流量了. #include<cstdio> #include<cstring> #include<cmath> #include<iostream> #

POJ2135:Farm Tour

http://poj.org/problem?id=2135 #include <iostream> #include <queue> #include <string.h> #include <stdlib.h> #include <algorithm> #include <math.h> #include <stdio.h> #define inf 0x3f3f3f3f using namespace std; int

poj2135(简单的最小费用流问题)

题目链接:http://poj.org/problem?id=2135 Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10862   Accepted: 4024 Description When FJ's friends visit him on the farm, he likes to show them around. His farm comprises N (1 <= N <= 1000

POJ Farm Tour

Farm Tour 题目: 约翰有N块地,家在1号,而N号是个仓库.农场内有M条道路(双向的),道路i连接这ai号地和bi号地,长度为ci. 约翰希望依照从家里出发,经过若干地后达到仓库.然后再返回家中.假设要求往返不能经过同一条道路两次,求參观路线总长度最小值. 算法分析: 用最短路求解然后在删除第一次最短路中的边在求解一次最短路.这样是否可行?应该立即就能找到反例证明该方法不能总得到最优结果吧. 于是我们放弃把问题当作去和回的这样的想法,转而将问题当作求从1号顶点到N号顶点的两条没有公共边的

poj 2135 Farm Tour (最小费用最大流模板)

网络流的费用: 在实际应用中,与网络流有关的问题,不仅涉及流量,而且还有费用的因素.网络的每一条边(v,w)除了给定容量cap(v,w)外,还定义了一个单位流量费用cost(v,w) 最小费用最大流问题 给定网络G,要求G的一个最大用流flow,使流的总费用最小. 求解MCMF问题的算法: 最小费用最大流最常用和基本的算法我们可以称它为最小费用路算法,其思想与求最大流的增广路算法类似,不断在残流网络中寻找从源s到汇t的最小费用路,即残流网络中从s到t的以费用为权的最短路,然后沿最小费用路增流,直