关闭

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

标签: ACMpoj
331人阅读 评论(0) 收藏 举报
分类:
Farm Tour
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 14530   Accepted: 5540

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

题意:先从第一个点到第n个点,再从第n个点到第一个点,同一条路只能走一遍,问最短路是多少?

思路:因为同一条路只能走一遍,我们可以用网络流来做,每条路的流量都是1,这样就只能走一次了。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
#define N 1010
#define M 10010
#define INF 0x3f3f3f3f
struct Node
{
    int from,to,next,cap,cost;///起点,终点,同起点下一条边,残余流量,费用
}edge[M<<2];
int cnt,head[N];
int vis[N],d[N],pp[N];
int sumflow;///最大流量总和
void init()
{
    cnt=0;
    memset(head,-1,sizeof(head));
}
void addedge(int from,int to,int cap,int cost)
{
    edge[cnt].from=from;edge[cnt].to=to;edge[cnt].cost=cost;edge[cnt].cap=cap;
    edge[cnt].next=head[from];head[from]=cnt++;
    edge[cnt].from=to;edge[cnt].to=from;edge[cnt].cost=-cost;edge[cnt].cap=0;
    edge[cnt].next=head[to];head[to]=cnt++;///存反向边
}
int spfa(int s,int t,int n)
{
    queue<int>q;
    memset(vis,0,sizeof(vis));
    memset(pp,-1,sizeof(pp));///pp[i]表示最短路径上以i为终点的边的编号
    for(int i=0;i<=n;i++)
        d[i]=INF;
    d[s]=0;
    vis[s]=1;
    q.push(s);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].to;
            if(edge[i].cap>0&&d[v]>d[u]+edge[i].cost)
            {
                d[v]=d[u]+edge[i].cost;
                pp[v]=i;
                if(!vis[v])
                {
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    if(d[t]==INF) return 0;///找不到一条到终点的路
    return 1;
}
int MCMF(int s,int t,int n)
{
    int mincost=0,minflow,flow=0;///最小费用,路径中最小流量,总流量
    while(spfa(s,t,n))///找当前的最短路
    {
        minflow=INF+1;
        for(int i=pp[t];i!=-1;i=pp[edge[i].from])
            minflow=min(minflow,edge[i].cap);///从路径中找最小的流量
        flow+=minflow;///总流量加上最小流量
        for(int i=pp[t];i!=-1;i=pp[edge[i].from])
        {
            edge[i].cap-=minflow;///当前边减去最小流量
            edge[i^1].cap+=minflow;///反向边加上最小流量
        }
        mincost+=d[t]*minflow;///最小费用等于路径和*每条路径的流量(经过多少次)
    }
    sumflow=flow;
    return mincost;
}
int main()
{
    int n,m;
    int from,to,cost;
    while(~scanf("%d %d",&n,&m))
    {
        init();
        for(int i=0;i<m;i++)
        {
        scanf("%d %d %d",&from,&to,&cost);
        addedge(from,to,1,cost);
        addedge(to,from,1,cost);
        }
        int S=0,T=n+1;
        addedge(S,1,2,0);
        addedge(n,T,2,0);
        int ans=MCMF(S,T,T);///流量为2保证只会走两次,如果是1到n有可能走多次
        printf("%d\n",ans);
    }
    return 0;
}


0
0
查看评论

poj2135 - Farm Tour

想看更多的解题报告:http://blog.csdn.net/wangjian8006/article/details/7870410              ...
  • wangjian8006
  • wangjian8006
  • 2012-09-03 15:33
  • 1851

POJ_2135_Farm Tour(最小费用流)

题意:给你一副无向图,问从1->n->1这样走一个来回所用的最短路径是多少,每条边只能走一次。 分析:最小费用流问题。把边的长度当成费用,每条边容量为1,由于是无向图,所以每条边要处理两次,即u->v,v->u都要加进去。把图建好后跑一遍流量为2的最小费用流得出最小费用即可...
  • jhgkjhg_ugtdk77
  • jhgkjhg_ugtdk77
  • 2015-09-11 11:48
  • 562

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

POJ 2135 Farm Tour(最小费用最大流) http://poj.org/problem?id=2135 题意:        FJ带朋友参观自己的农场,从自己的房子出发到农场,再从农场返回自己的房子,要求过去和回来不走同一条路...
  • u013480600
  • u013480600
  • 2014-09-03 15:50
  • 807

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

Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14530   Accepted: 5540 ...
  • hexianhao
  • hexianhao
  • 2016-08-01 17:17
  • 346

【POJ】2135 Farm Tour 最小费用最大流

题目传送门 这题用到了最小费用最大流,一条边的容量为1,代价为这条边的长度。 建立超级源点通向节点1,容量为2,代价为0;节点n通向超级汇点,容量为2,代价为0。 之后刷一遍最小费用最大流就行了。 注意:这题里的边都是双向边,比方说从节点x到节点y和从节点y到节点x是不同的走法。 附上AC...
  • lyfsb
  • lyfsb
  • 2017-04-16 20:57
  • 372

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

Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14241   Accepted: 5430 Description When FJ's friends visit...
  • hyf20144055065
  • hyf20144055065
  • 2016-04-02 16:40
  • 318

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

大意:从1点走到n点然后再返回到1点,前提是所有的路程只能够走一次。思路:因为从原点走到n点然后再走回来需要走源点两次,所以流量为2.因为所有的路都是双向图,即需要建四条边。#include<iostream> #include<cstdio> #include<cst...
  • Grit_ICPC
  • Grit_ICPC
  • 2016-04-30 12:51
  • 227

poj 2135 Farm Tour 【最小费用最大流】

Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13464   Accepted: 5101 Description Whe...
  • chenzhenyu123456
  • chenzhenyu123456
  • 2015-08-27 17:02
  • 625

Farm Tour POJ - 2135 最小费用最大流

传送门:POJ2135 题意:给出n个点和m条边,每条边只能走一次,问从1走到n再走回1的最小路程是多少。 思路:看完题我第一反应这不是最短路么。。求两遍最短路就好了啊。。仔细想想却很难实现,因为有重边,所以要用链式前向星法建图,但这样的话就会很难删边。 正解:最小费用最大流,源点到1号点容量...
  • lxy767087094
  • lxy767087094
  • 2017-04-30 21:08
  • 175

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

POJ 2135 Farm Tour  (最小费用最大流) 两遍spfa解决 #include #include #include #include #include using namespace std; const int maxn=30000; co...
  • a1061747415
  • a1061747415
  • 2013-08-26 13:54
  • 685
    个人资料
    • 访问:143101次
    • 积分:5243
    • 等级:
    • 排名:第6222名
    • 原创:396篇
    • 转载:11篇
    • 译文:0篇
    • 评论:21条
    最新评论