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. C语言学习_一个简单程序的解释与C学习方法概括

    简单计算器程序示例: # include <stdio.h> //1.头文件 //2.加法函数 int add(int a,int b)//3.函数定义方式 { //4.函数体 retur ...

  2. linux —— 搭建网页项目笔记

    导读 本文笔记之用,记录在我在linux下搭建与开发网站时遇到的一些碎片知识,以备将来之需. 目录 数据库相关 1.数据库相关 1) ubuntu 16.04 LTS 下mysql 的安装与使用  安 ...

  3. uva 11300 - Spreading the Wealth(数论)

    题目链接:uva 11300 - Spreading the Wealth 题目大意:有n个人坐在圆桌旁,每个人有一定的金币,金币的总数可以被n整除,现在每个人可以给左右的人一些金币,使得每个人手上的 ...

  4. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(19)-权限管理系统-用户登录

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(19)-权限管理系统-用户登录 我们之前做了验证码,登录界面,却没有登录实际的代码,我们这次先把用户登录先 ...

  5. ColorComboBox

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; u ...

  6. 汉诺塔-Hanoi

    1. 问题来源: 汉诺塔(河内塔)问题是印度的一个古老的传说. 法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针.印度教的主神梵 ...

  7. 覆盖equals的时候总要覆盖hashCode

    import java.util.HashMap; public class Student { private String name ; private String id; public Stu ...

  8. Java基础知识强化之集合框架笔记43:Set集合之TreeSet存储Integer类型的元素并遍历

    1. TreeSet类概述: • 能够对元素按照某种规则进行排序. • 或者根据创建set时提供的Comparator进行排序 • 具体取决于使用的构造方法 2. 代码示例: package cn.i ...

  9. 【Android】数据的应用-使用sharedpreferences存储数据

    Android应用开发SharedPreferences存储数据的使用方法 SharedPreferences是Android中最容易理解的数据存储技术,实际上SharedPreferences处理的 ...

  10. Myeclipse快捷键的设置