Farm Tour(网络流模板题)

题目描述

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.

输入

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

输出

A single line
containing the length of the shortest tour.

样例输入

4 5
1 2 1
2 3 1
3 4 1
1 3 2
2 4 2

样例输出

6
#include<cstdio>
#include<cstring>
struct edge{
    int to,cap,rev,nx,we;
}G[40050];
int n,m,p;
int h[2050],q[40050],d[2050];
bool mark[2050];
int Min(int a,int b){return a<b?a:b;}
void ae(int s,int e,int c,int w){
    G[++p]=(edge){e,c,p+1,h[s],w};h[s]=p;
    G[++p]=(edge){s,0,p-1,h[e],-w};h[e]=p;
}
bool spfa(){
    memset(d,127/3,sizeof(d));
    memset(mark,0,sizeof(mark));
    d[n+1]=0;mark[n+1]=1;
    int head=0,tail=0;
    int inf=d[0];
    q[tail++]=n+1;
    while(head!=tail){
        int fr=q[head++];
        for(int i=h[fr];i;i=G[i].nx){
            if(G[G[i].rev].cap>0&&d[G[i].to]>d[fr]+G[G[i].rev].we){
                d[G[i].to]=d[fr]+G[G[i].rev].we;
                if(!mark[G[i].to])mark[G[i].to]=1,q[tail++]=G[i].to;
            }
        }
        mark[fr]=0;
    }
    return !(d[0]==inf);
}
int dfs(int s,int t,int f){
    mark[s]=1;
    if(s==t) return f;
    int sum=0;
    for(int i=h[s];i;i=G[i].nx){
        if(G[i].cap>0&&!mark[G[i].to]&&d[s]-G[i].we==d[G[i].to]){
            int d=dfs(G[i].to,t,Min(G[i].cap,f));
            if(d)sum+=d,f-=d,G[i].cap-=d,G[G[i].rev].cap+=d;
            if(f==0)return sum;
        }
    }
    return sum;
}
int m__f(){
    int sum=0;
    while(spfa()){
        mark[n+1]=1;
        while(mark[n+1]){
            memset(mark,0,sizeof(mark));
            sum+=dfs(0,n+1,99999999)*d[0];
        }
    }
    return sum;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        ae(x,y,1,z);ae(y,x,1,z);
    }
    ae(0,1,2,0);ae(n,n+1,2,0);
    printf("%d\n",m__f());
    return 0;
}  
时间: 2024-11-06 05:26:56

Farm Tour(网络流模板题)的相关文章

HDU 3549 Flow Problem(网络流模板题)

记录一下模板 #include <vector> #include <cstring> #include <algorithm> #include <cstdio> #include <queue> using namespace std; #define maxn 1100 #define INF 0x7f7f7f7f struct Edge { int from,to,cap,flow; }; struct Dinic { int n,m,s

USACO 4.2 Drainage Ditches(网络流模板题)

Drainage DitchesHal Burch Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover patch. This means that the clover is covered by water for awhile and takes quite a long time to regrow. Thus, Farmer John has built a se

POJ 2135 Farm Tour(网络流之费用流)

题目地址:POJ 2135 来回走一遍可以看成从源点到汇点走两遍.将每个点的流量设为1,就可以保证每条边不重复.然后跑一次费用流就行了.当流量到了2之后停止,输出此时的费用. #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <qu

网络流(最小费用最大流):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的以费用为权的最短路,然后沿最小费用路增流,直

POJ 2135 Farm Tour (dinic算法,网络流)

构图方法: 注意题目中的边为无向边.新建源点s 和 汇点t 每两条道路连一条容量为1,费用为w的边.s到1连一条容量为1,费用为0 的边,n到 t 连一条容量为1,费用为0 的边,求最大流. #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> #include <queue> #include

poj 1739 Tony&#39;s Tour 插头dp模板题

题意: 给一个迷宫,求左下角到右下角的路径数. 分析: 插头dp的模板题,建议先看cdq的论文再看代码,这份代码在模板基础上略微有改动.论文地址http://wenku.baidu.com/view/ed2b3e23482fb4daa58d4b74.html 代码: #include <iostream> using namespace std; const int maxD=16; const int HASH=10007; const int STATE=1000024; int N,M;

【网络流#2】hdu 1533 最小费用最大流模板题

嗯~第一次写费用流题... 这道就是费用流的模板题,找不到更裸的题了 建图:每个m(Man)作为源点,每个H(House)作为汇点,各个源点与汇点分别连一条边,这条边的流量是1(因为每个源点只能走一条边到汇点),费用是 从源点走到汇点的步数,因为有多个源点与汇点,要建一个超级源点与超级汇点,超级源点与各个源点连一条流量为1,费用为0(要避免产生多余的费用)的边 按照这个图跑一发费用流即可 把代码挂上去,用的是前向星写的 1 #include<cstdio> 2 #include<cstr

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