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. 用python 装饰器打log

    # coding=utf-8    from time import time def logged(when):     def log(f,*args,**kargs):         prin ...

  2. 善用VS中的Code Snippet来提高开发效率 分类: C# 2015-01-22 11:06 69人阅读 评论(0) 收藏

    前言  在谈谈VS中的模板中,我介绍了如何创建项目/项模板,这种方式可以在创建项目时省却不少重复性的工作,从而提高开发效率.在创建好了项目和文件后,就得开始具体的编码了,这时又有了新的重复性工作,就是 ...

  3. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(21)-权限管理系统-跑通整个系统

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(21)-权限管理系统-跑通整个系统 这一节我们来跑通整个系统,验证的流程,通过AOP切入方式,在访问方法之 ...

  4. MySQL Replication主从复制

    MySQL Replication:NySQL复制,MySQL的复制默认为异步工作模式   mysql的复制功能是mysql内置的,装上它之后就具备了这个功能,而mysql复制是mysql实现大规模高 ...

  5. SqlServer快捷键整理

    一:sp_helptext 对象 1.Ctrl+D 表格显示 2.Ctrl+T 文本显示(含格式)

  6. js鼠标事件

    今天遇到一个非常奇怪而又搞笑的事情:给一个a标签添加一个鼠标移动上时给一个事件,我给其添加的是一个onMouseMove事件,结果在IE6 7 8 9和GOOLE中都很正常,结果在Firox中出现问题 ...

  7. 观察者模式-Observer

    观察者模式很好理解,简单来说就是:当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是一种一对多的关系. 1. 自己手工创建Observer模式 首先,创建观察者接口: pub ...

  8. AndroidStudyDemo之Android4.x介绍

    Android4.x 思维导图 作者:李旺成 时间:2016年4月7日 AndroidStudyDemo 系列篇章开始了!!! AndroidStudyDemo 你值得拥有AndroidStudyDe ...

  9. date和long的相互转换

    import java.text.SimpleDateFormat; import java.util.Date; public class T { public static void main(S ...

  10. css3购物网站商品文字提示实例

    css3购物网站商品文字提示实例先来看效果图:<ignore_js_op> 当鼠标划过图片时,有着泰迪熊黑色长方形的背景就会出现.来看HTML5+CSS3代码: <!DOCTYPE ...