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 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

题意:FJ带朋友参观自己的农场,从自己的房子出发到农场,再从农场返回自己的房子,要求去回不走同一条路。房子的点数为1,农场为n,在1到n之间有很多点,给出n个顶点,m条边,然后m行每行有三个数,a,b,c代表a到c的路径长度为c,并且a到b是无向边,现在要求从1点到n点在从n点返回1点的最短路(摘自贰圣的博客)

题解:将路的长度看成费用,路的条数看成流,然后添加附加源汇点就构成了最小费用最大流问题。第22行-f是因为每条路只能走一次,如果走了两次那么两次的费用相互抵消,相当于这条路没走过。

#include <stdio.h>
#include <string.h>
#include <queue>
#define inf 0x3f3f3f3f
#define maxn 1010
#define maxm 10010
using std::queue;

int head[maxn];
struct Node {
    int u, v, next, c, f; // c是容量,f是费用
} E[maxm << 2];
int n, m, id;
int dist[maxn], load[maxn];
bool vis[maxn];

void addEdge(int u, int v, int f, int c) {
    E[id].u = u; E[id].v = v; E[id].c = c;
    E[id].f = f; E[id].next = head[u];
    head[u] = id++;
    E[id].u = v; E[id].v = u; E[id].c = 0;
    E[id].f = -f; E[id].next = head[v];
    head[v] = id++;
}

void getMap() {
    memset(head, -1, sizeof(int) * (n + 2));
    int u, v, f; id = 0;
    while(m--) {
        scanf("%d%d%d", &u, &v, &f);
        addEdge(u, v, f, 1);
        addEdge(v, u, f, 1);
    }
    addEdge(0, 1, 0, 2); // u, v, f, c
    addEdge(n, n + 1, 0, 2);
}

bool SPFA(int start, int end) {
    queue<int> Q; int i, u, v;
    memset(vis, 0, sizeof(bool) * (n + 2));
    memset(load, -1, sizeof(int) * (n + 2));
    memset(dist, 0x3f, sizeof(int) * (n + 2));
    Q.push(start); vis[start] = 1; dist[start] = 0;
    while(!Q.empty()) {
        u = Q.front(); Q.pop();
        vis[u] = 0;
        for(i = head[u]; i != -1; i = E[i].next) {
            v = E[i].v;
            if(E[i].c && dist[v] > dist[u] + E[i].f) {
                dist[v] = dist[u] + E[i].f;
                load[v] = i;
                if(!vis[v]) {
                    vis[v] = 1; Q.push(v);
                }
            }
        }
    }
    return dist[end] != inf;
}

int Min_Cost_Flow(int start, int end) {
    int ans_cost = 0;
    int u, minCut;
    while(SPFA(start, end)) {
        minCut = inf;
        for(u = load[end]; u != -1; u = load[E[u].u]) {
            if(minCut > E[u].c)
                minCut = E[u].c;
        }
        for(u = load[end]; u != -1; u = load[E[u].u]) {
            E[u].c -= minCut;
            E[u^1].c += minCut;
        }
        ans_cost += dist[end] * minCut;
    }
    return ans_cost;
}

int main() {
    // freopen("stdin.txt", "r", stdin);
    while(scanf("%d%d", &n, &m) == 2) {
        getMap();
        printf("%d\n", Min_Cost_Flow(0, n + 1));
    }
    return 0;
}
时间: 2024-08-07 18:04:27

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

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

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

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

hdu 1853 Cyclic Tour 最小费用最大流

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

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

Farm Tour Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: 2135 64-bit integer IO format: %lld      Java class name: Main When FJ's friends visit him on the farm, he likes to show them around. His farm compris

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

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

no-understand 最小费用最大流-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 &

poj2135最小费用最大流经典模板题

Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13509   Accepted: 5125 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]最小费用最大流

一直由于某些原因耽搁着...最小费用最大流没有搞会. 今天趁着个人状态正佳,赶紧去看看,果然30min不到看会了算法+模板并且A掉了一道题. 感觉最小费用最大流在学过了最大流之后还是挺好理解的.找到从起点到终点流过1单位流量的最小花费方案,然后更新数据. 不停地找增广路,不停累计答案,不停趋近最优解. 理解起来没有任何问题.代码书写一遍就过了很顺利. POJ2135 实际上是一道并不那么容易套的模板题. 网络流的题目重在建模.这道题就是这样. 求起点到终点往返的最短路径,但不能经过相同的边. 往

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