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

Farm Tour

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 18150   Accepted: 7023

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

Source

USACO 2003 February Green

//题意:n 个点, m 条无向边,要求从 1 走到 n 点,再从 n 走到 1 点,不能走重复路,求最短路径

//可以看成从 1 走到 n 用两种路径,因为只能走一遍,所以边的容量为 1

所以建立一个附加的源点容量为2,费用为 0 到1点,附加的汇点容量为 2 ,费用为 0 到 n+1 点跑最小费用最大流即可

  1 //# include <bits/stdc++.h>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <vector>
  5 #include <queue>
  6 using namespace std;
  7 # define eps 1e-8
  8 # define INF 0x3f3f3f3f
  9 # define pi  acos(-1.0)
 10 # define MXN  1005
 11 # define MXM  20050
 12
 13 struct Edge{
 14     int from, to, flow, cost, cap;
 15 }edges[MXM*2];            //有向边数*2
 16
 17 struct MCMF{
 18     int n, m, idx;    //点,边,边数
 19     int flow, cost;
 20     vector<int> G[MXN];     //记录边
 21     int inq[MXN];           //BFS用
 22     int dis[MXN];           //层次
 23     int pre[MXN];           //上一条弧
 24     int adf[MXN];           //增量
 25
 26     void Init(){
 27         idx=0;
 28         for (int i=0;i<=n+1;i++) G[i].clear();    //有附加点时要注意
 29     }
 30
 31     void Addedge(int u,int v,int cost,int cap){
 32         edges[idx++] = (Edge){u,v,0,cost,cap};
 33         edges[idx++] = (Edge){v,u,0,-cost,0};
 34         G[u].push_back(idx-2);
 35         G[v].push_back(idx-1);
 36     }
 37
 38     int Bellman(int s, int t)
 39     {
 40         memset(dis,0x3f,sizeof(dis));   //有附加点时要注意
 41         memset(inq,0,sizeof(inq));
 42         dis[s]=0, inq[s]=1, adf[s]=INF;
 43         queue<int> Q;
 44         Q.push(s);
 45         while (!Q.empty())
 46         {
 47             int u = Q.front(); Q.pop();
 48             inq[u]=0;
 49             for (int i=0;i<(int)G[u].size();i++)
 50             {
 51                 Edge &e = edges[G[u][i]];
 52                 if (dis[e.to] > dis[u] + e.cost && e.cap > e.flow)
 53                 {
 54                     dis[e.to] = dis[u] + e.cost;
 55                     adf[e.to] = min(adf[u], e.cap-e.flow);
 56                     pre[e.to] = G[u][i];
 57                     if (!inq[e.to])
 58                     {
 59                         Q.push(e.to);
 60                         inq[e.to]=1;
 61                     }
 62                 }
 63             }
 64         }
 65         if (dis[t]==INF) return false;
 66
 67         flow+=adf[t];
 68         cost+=adf[t]*dis[t];
 69         int x=t;
 70         while(x!=s)
 71         {
 72             edges[pre[x]].flow+=adf[t];
 73             edges[pre[x]^1].flow-=adf[t];
 74             x=edges[pre[x]].from;
 75         }
 76         return true;
 77     }
 78
 79     int MinCost(int s,int t)
 80     {
 81         flow = 0, cost = 0;
 82         while(Bellman(s, t));
 83         return cost;
 84     }
 85 }F;
 86
 87 int main()
 88 {
 89     scanf("%d%d",&F.n,&F.m);
 90     F.Init();
 91     for (int i=1;i<=F.m;i++)
 92     {
 93         int u,v,cost;
 94         scanf("%d%d%d",&u,&v,&cost);
 95         F.Addedge(u,v,cost,1);
 96         F.Addedge(v,u,cost,1);
 97     }
 98     F.Addedge(0, 1, 0, 2);
 99     F.Addedge(F.n, F.n+1, 0, 2);
100     printf("%d\n",F.MinCost(0,F.n+1));
101     return 0;
102 }

时间: 2024-11-13 10:03:48

Farm Tour(最小费用最大流模板)的相关文章

POJ 2135 Farm Tour [最小费用最大流]

题意: 有n个点和m条边,让你从1出发到n再从n回到1,不要求所有点都要经过,但是每条边只能走一次.边是无向边. 问最短的行走距离多少. 一开始看这题还没搞费用流,后来搞了搞再回来看,想了想建图不是很难,因为要保证每条边只能走一次,那么我们把边拆为两个点,一个起点和终点,容量是1,权重是这条路的长度.然后两个端点分别向起点连接容量是1权重是0的边,终点分别向两个端点连容量是1权重是0的边,从源点到1连容量为2权重为0的边,从n到汇点连容量为2权重为0的边. #include<stdio.h>

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

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

POJ2135Farm Tour(最小费用最大流模板)

题目链接:http://poj.org/problem?id=2135 题意:农场主想从1到n,然后从n到1,每条边最多走一次,不能走重复的路,问最短距离是多少. 建图:取超级源点s,并与房子连一条边,容量为2,费用为0:取barn与超级汇点 t 的边的容量为2,费用为0 房子与barn的费用为距离,容量为1 #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring>

POJ2135 最小费用最大流模板题

练练最小费用最大流 此外此题也是一经典图论题 题意:找出两条从s到t的不同的路径,距离最短. 要注意:这里是无向边,要变成两条有向边 #include <cstdio> #include <cstring> #define MAXN 1005 #define MAXM 10005 #define INF 0x3f3f3f3f struct Edge { int y,c,w,ne;//c容量 w费用 }e[MAXM*4]; int n,m,x,y,w; int s,t,Maxflow

poj 2195 最小费用最大流模板

/*Source Code Problem: 2195 User: HEU_daoguang Memory: 1172K Time: 94MS Language: G++ Result: Accepted Source Code */ #include <iostream> #include <stdio.h> #include <queue> #include <math.h> #include <string.h> using namespa

HDU 1533--Going Home【最小费用最大流 &amp;&amp; 模板】

Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3452    Accepted Submission(s): 1771 Problem Description On a grid map there are n little men and n houses. In each unit time, every

Doctor NiGONiGO’s multi-core CPU(最小费用最大流模板)

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=693 题意:有一个 k 核的处理器和 n 个工作,全部的工作都须要在一个核上处理一个单位的时间,每一个核在不同一时候间处理同一个工作的花费是递增的,每一个核一次仅仅能处理一个工作,求运用k个核处理这n个工作的最小花费. 分析: 分析可知,求处理全部工作的最小花费,而每次选择怎么处理我们能够通过容量都为1的边来让网络流处理,这样就转化为最小费用最大流. 首先设一个超级源点s,连接全部的工作

hdu 1853 Cyclic Tour 最小费用最大流

题意:一个有向图,现在问将图中的每一个点都划分到一个环中的最少代价(边权和). 思路:拆点,建二分图,跑最小费用最大流即可.若最大流为n,则说明是最大匹配为n,所有点都参与,每个点的入度和出度又是1,所以就是环. /********************************************************* file name: hdu1853.cpp author : kereo create time: 2015年02月16日 星期一 17时38分51秒 *******

POJ-2195 Going Home(最小费用最大流模板)

题目链接:POJ-2195 Going Home 题意 给出$N$行$M$列的网格,'m'表示人,'H'表示房子,且'm'和'H'的数量相同,一个人只能进一间房子,一间房子也只能给一个人进去,人可走上下左右四个方向,现在要让所有人进入房子,求最短路径和. 思路 这是一个二分图带权最小匹配问题,可直接用最小费用最大流求解. 源点向人各连一条容量为1,费用为0的边,每个人向每间房子连容量为1,费用为距离的边,每间房子向汇点连容量为1,费用为0的边,然后跑最小费用最大流即可. 代码实现 #includ