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.

//最小费用流

//问题描述:有n个点m条边组成的农场,有正边权,fj闲着没事干带游客绕农场兜一圈

//他希望这次旅行越短越好,每条边部能重复走,问题等价于在网络中找两条互不相交的s-t的路线

//用费用流求解,把双向边看成两条单向的,容量为1,费用为边权,增加两个点s,t

//s到1容量为2,n到t容量为2,然后求解即可

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

最小费用流

题解:就在description里。。。。

code:

spfa费用流:

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define maxn 2005
#define maxm 40050
#define INF 1061109567
using namespace std;
char ch;
int n,m,a,b,c;
struct mincost_flow{
int st,en,tot,now[maxn],son[maxm],pre[maxm],val[maxm],cost[maxm];
int dist[maxn],list[maxn],pe[maxn],head,tail;
bool bo[maxn];
int flow,sum;
void clear(){
tot=;
memset(now,,sizeof(now));
}
void put(int a,int b,int c,int d){
pre[++tot]=now[a];
now[a]=tot;
son[tot]=b;
val[tot]=c;
cost[tot]=d;
}
bool spfa(){
memset(bo,,sizeof(bo));
memset(pe,,sizeof(pe));
memset(dist,,sizeof(dist));
list[]=st,bo[st]=true,dist[st]=,head=,tail=;
while (head!=tail){
if (++head==maxn) head=;
int u=list[head];
for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
if (dist[v]>dist[u]+cost[p]&&val[p]){
dist[v]=dist[u]+cost[p],pe[v]=p;
if (!bo[v]){
if (++tail==maxn) tail=;
list[tail]=v,bo[v]=true;
}
}
bo[u]=false;
}
if (dist[en]==INF) return false;
int tmp=INF,t=;
for (int u=en,p=pe[u];u!=st;u=son[p^],p=pe[u]) tmp=min(tmp,val[p]);
for (int u=en,p=pe[u];u!=st;u=son[p^],p=pe[u]) val[p]-=tmp,val[p^]+=tmp,t+=cost[p];
flow+=tmp,sum+=t*tmp;
return true;
}
void calc(){
flow=sum=;
for (;spfa(););
}
}T;
void read(int &x){
for (ch=getchar();!isdigit(ch);ch=getchar());
for (x=;isdigit(ch);x=x*+ch-'',ch=getchar());
}
int main(){
read(n),read(m);
T.clear(),T.st=,T.en=n+,T.put(,,,),T.put(,,,),T.put(n,n+,,),T.put(n+,n,,);
for (int i=;i<=m;i++) read(a),read(b),read(c),T.put(a,b,,c),T.put(b,a,,-c),T.put(b,a,,c),T.put(a,b,,-c);
T.calc();
printf("%d\n",T.sum);
return ;
}

zkw费用流:

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#define maxn 1005
#define maxm 40010
#define inf 1061109567
using namespace std;
char ch;
bool ok;
void read(int &x){
for (ok=,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=;
for (x=;isdigit(ch);x=x*+ch-'',ch=getchar());
if (ok) x=-x;
}
int n,m,a,b,d;
struct zkw_costflow{
int s,t,tot,now[maxn],son[maxm],pre[maxm],val[maxm],cost[maxm];
int dis[maxn],totflow,totcost,tmp,sla[maxn];
bool bo[maxn];
void init(){s=,t=n+,tot=,memset(now,,sizeof(now));}
void put(int a,int b,int c,int d){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c,cost[tot]=d;}
void add(int a,int b,int c,int d){put(a,b,c,d),put(b,a,,-d);}
int dfs(int u,int rest,int totval){
if (u==t){totcost+=rest*totval;return rest;}
int ans=; bo[u]=;
for (int p=now[u],v=son[p];p&&rest;p=pre[p],v=son[p])
if (val[p]&&!bo[v]){
int d=cost[p]+dis[u]-dis[v];
if (!d){
int d=dfs(v,min(rest,val[p]),totval+cost[p]);
val[p]-=d,val[p^]+=d,ans+=d,rest-=d;
}
else sla[v]=min(sla[v],d);
}
return ans;
}
bool relax(){
int d=inf;
for (int u=s;u<=t;u++) if (!bo[u]) d=min(d,sla[u]);
if (d==inf) return false;
for (int u=s;u<=t;u++) if (!bo[u]) dis[u]+=d;
return true;
}
void work(){
memset(dis,,sizeof(dis)),totflow=totcost=;
do{
memset(sla,,sizeof(sla));
do{
memset(bo,,sizeof(bo));
tmp=dfs(s,inf,),totflow+=tmp;
}while (tmp);
}while (relax());
}
}f;
int main(){
read(n),read(m),f.init(),f.add(f.s,,,),f.add(n,f.t,,);
for (int i=;i<=m;i++) read(a),read(b),read(d),f.add(a,b,,d),f.add(b,a,,d);
f.work();
printf("%d\n",f.totcost);
return ;
}

消负圈费用流:

 #include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#define maxn 1005
#define maxm 40010
#define inf 1061109567
using namespace std;
char ch;
bool ok;
void read(int &x){
for (ok=,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=;
for (x=;isdigit(ch);x=x*+ch-'',ch=getchar());
if (ok) x=-x;
}
int n,m,a,b,d;
struct costflow{
int s,t,tot,now[maxn],son[maxm],pre[maxm],val[maxm],cost[maxm];
int dis[maxn],head,tail,list[maxn];
int top,stack[maxn],idx,path[maxn];
bool in[maxn],bo[maxn];
int totflow,totcost;
void init(){s=,t=n+,tot=,memset(now,,sizeof(now));}
void put(int a,int b,int c,int d){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c,cost[tot]=d;}
void add(int a,int b,int c,int d){put(a,b,c,d),put(b,a,,-d);}
bool bfs(){
memset(bo,,sizeof(bo));
head=,tail=,list[]=s,dis[s]=,bo[s]=;
while (head<tail){
int u=list[++head];
for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
if (val[p]&&!bo[v]) bo[v]=,dis[v]=dis[u]+,list[++tail]=v;
}
return bo[t];
}
int dfs(int u,int rest,int totval){
if (u==t){totcost+=rest*totval;return rest;}
int ans=;
for (int p=now[u],v=son[p];p&&rest;p=pre[p],v=son[p])
if (val[p]&&dis[v]==dis[u]+){
int d=dfs(v,min(rest,val[p]),totval+cost[p]);
val[p]-=d,val[p^]+=d,ans+=d,rest-=d;
}
if (!ans) dis[u]=-;
return ans;
}
void dinic(){
totflow=totcost=;
while (bfs()) totflow+=dfs(s,inf,);
}
int spfa(int u){
in[u]=;
for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
if (val[p]&&dis[v]>dis[u]+cost[p]){
dis[v]=dis[u]+cost[p],path[v]=p;
if (in[v]) return v;
int t=spfa(v); if (t!=-) return t;
}
in[u]=; return -;
}
int find(){
memset(in,,sizeof(in));
memset(dis,,sizeof(dis));
memset(path,-,sizeof(path));
for (int i=s;i<=t;i++){
int u=spfa(i);
if (u!=-) return u;
}
return -;
}
void relax(int t){
int flow=inf,sum=,u;
for (u=t;son[path[u]^]!=t;u=son[path[u]^]) flow=min(flow,val[path[u]]),sum+=cost[path[u]];
flow=min(flow,val[path[u]]),sum+=cost[path[u]];
for (u=t;son[path[u]^]!=t;u=son[path[u]^]) val[path[u]]-=flow,val[path[u]^]+=flow;
val[path[u]]-=flow,val[path[u]^]+=flow,totcost+=flow*sum;
}
void work(){
dinic();
for (int t=find();t!=-;t=find()) relax(t);
}
}f;
int main(){
read(n),read(m),f.init(),f.add(f.s,,,),f.add(n,f.t,,);
for (int i=;i<=m;i++) read(a),read(b),read(d),f.add(a,b,,d),f.add(b,a,,d);
f.work();
printf("%d\n",f.totcost);
return ;
}

老oj2146 && Pku2135 Farm Tour的更多相关文章

  1. POJ2135 Farm Tour

      Farm Tour Time Limit: 2MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Description ...

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

    Farm Tour Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: ...

  3. POJ Farm Tour

    Farm Tour 题目: 约翰有N块地,家在1号,而N号是个仓库.农场内有M条道路(双向的),道路i连接这ai号地和bi号地,长度为ci. 约翰希望依照从家里出发,经过若干地后达到仓库.然后再返回家 ...

  4. [网络流]Farm Tour(费用流

    Farm Tour 题目描述 When FJ's friends visit him on the farm, he likes to show them around. His farm compr ...

  5. POJ 2135 Farm Tour (网络流,最小费用最大流)

    POJ 2135 Farm Tour (网络流,最小费用最大流) Description When FJ's friends visit him on the farm, he likes to sh ...

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

    Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18150   Accepted: 7023 Descri ...

  7. POJ2135 Farm Tour —— 最小费用最大流

    题目链接:http://poj.org/problem?id=2135 Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submis ...

  8. poj 2351 Farm Tour (最小费用最大流)

    Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 17230   Accepted: 6647 Descri ...

  9. poj 2135 Farm Tour 【无向图最小费用最大流】

    题目:id=2135" target="_blank">poj 2135 Farm Tour 题意:给出一个无向图,问从 1 点到 n 点然后又回到一点总共的最短路 ...

随机推荐

  1. java如何遍历hashMap

    通过Map的entrySet方法.将返回一个set集合.然后遍历这个set集合: package com.howlaa.day04; import java.util.HashMap; import ...

  2. HTTPClient实现java自动登录人人网

    参考网址: https://passport.csdn.net/account/login  http://www.iteye.com/topic/638206 httpClient http://b ...

  3. [置顶] js正则表达式的使用

    js中的正则表达式比起C#中的正则表达式要弱很多,但基本够用了 1定义正则表达式 2关于验证的三个这则表达式方法 3正则表达式式的转义字符 1定义正则表达式 在js中定义正则表达式很简单,有两种方式, ...

  4. Optimized Pagination using MySQL---reference

    Dealing with large data sets makes it necessary to pick out only the newest or the hottest elements ...

  5. ios的手势操作之UIGestureRecognizer浅析

    转载地址:http://blog.csdn.net/likendsl/article/details/7554150 每一个手势的实现例子,可参考下面网址:http://www.cnblogs.com ...

  6. 第二篇:从 GPU 的角度理解并行计算

    前言 本文从使用 GPU 编程技术的角度来了解计算中并行实现的方法思路. 并行计算中需要考虑的三个重要问题 1. 同步问题 在操作系统原理的相关课程中我们学习过进程间的死锁问题,以及由于资源共享带来的 ...

  7. [转] npm 模块安装机制简介

    npm 是 Node 的模块管理器,功能极其强大.它是 Node 获得成功的重要原因之一. 正因为有了npm,我们只要一行命令,就能安装别人写好的模块 . $ npm install 本文介绍 npm ...

  8. java按照集合中元素的属性进行排序示例代码

    public class Student { private String name; private int age; private int id; public Student() {  sup ...

  9. HTML简单介绍及常见元素

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  10. Spire.Barcode好用的条码生在组件

    由于项目的需要,今天在网上找了一下条码的组件,发现了一个简单易用的组件,使用简单,几句代码就搞定了.