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.lang.ClassCastException: Ljava.lang.Object; cannot be cast to com.entity.Advertisem异常

    今天一不小心就碰到了这样的问题,以前从来没有碰到过,在网上搜了很多办法,思路正确,但是还是要根据自己的程序改变. 一开始写的是hql语句进行统计每个月的数据,但是试了很久,程序一直提醒hql语句异常, ...

  2. HDU 2191 (13.12.2)

    悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Jav ...

  3. GB2312转换成UTF-8与utf_8转换成GB2312

    本文转载:http://www.cnblogs.com/jonhson/archive/2010/08/10/1796536.html /// <summary> /// utf_8转换成 ...

  4. spring mvc DispatcherServlet详解之二---request通过Controller获取ModelAndView过程

    整个spring mvc的架构如下图所示: 上篇文件讲解了DispatcherServlet通过request获取控制器Controller的过程,现在来讲解DispatcherServletDisp ...

  5. 第六篇:python高级之网络编程

    python高级之网络编程   python高级之网络编程 本节内容 网络通信概念 socket编程 socket模块一些方法 聊天socket实现 远程执行命令及上传文件 socketserver及 ...

  6. 关于ADO.NET的一些知识整理

    ADO.NET是什么 虽然我们都知道ADO.NET是对数据库的操作,但是要真的说出ADO.NET的具体含义还不是很容易. ADO.NET是ActiveX Data Objects的缩写,它是一个COM ...

  7. C#使用Process类调用外部程序(转)

    在程序开发中,一个程序经常需要去调用其他的程序,C#中Process类正好提供了这样的功能.它提供对本地和远程进程的访问并使您能够启动和停止本地系统进程.一.启动进程实例 Process myProc ...

  8. Flyweight 模式

    如果一个应用程序使用了太多的对象, 就会造成很大的存储开销. 特别是对于大量轻量级 (细粒度)的对象,比如在文档编辑器的设计过程中,我们如果为每个字母创建一个对象的话,系统可能会因为大量的对象而造成存 ...

  9. iOS 数据持久性存储-对象归档

    对象归档是将对象归档以文件的形式保存到磁盘中(也称为序列化,持久化),使用的时候读取该文件的保存路径读取文件的内容(也称为解档,反序列化) 主要涉及两个类:NSKeyedArichiver.NSKey ...

  10. Mac使用rz、sz远程上传下载文件

    习惯了 在windows下的securecrt和xshell的rz 和sz. rz 可以很方便的从客户端传文件到服务器,sz也可以很方便的从服务器传文件到客户端,就算中间隔着跳板机也不影响.在mac下 ...