最小费用最大流问题是经济学和管理学中的一类典型问题。在一个网络中每段路径都有“容量”和“费用”两个限制的条件下,此类问题的研究试图寻找出:流量从A到B,如何选择路径、分配经过路径的流量,可以在流量最大的前提下,达到所用的费用最小的要求。如n辆卡车要运送物品,从A地到B地。由于每条路段都有不同的路费要缴纳,每条路能容纳的车的数量有限制,最小费用最大流问题指如何分配卡车的出发路径可以达到费用最低,物品又能全部送到。

#include<stdio.h>

#include<queue>

#include<iostream>

#define inf  999999999

using namespace std;

#define N 11000

struct node {

int u,v,c,f,next;

}bian[N*4];

int dis[N],yong,head[N],sum,pre[N],n;

void Ad(int u,int v,int c,int f) {

bian[yong].u=u;

bian[yong].v=v;

bian[yong].c=c;//权值

bian[yong].f=f;//能用几次

bian[yong].next=head[u];//head数组用来记录上一个边的下标

head[u]=yong++;//当前边的下标

}

void Add(int u,int v,int c,int f) {

Ad(u,v,c,f);

Ad(v,u,-c,0);

}

int spfa(int s,int t) {//单源最短路采取的方法是动态逼近法:设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。

//定理: 只要最短路径存在,上述SPFA算法必定能求出最小值。

//证明:每次将点放入队尾,都是经过松弛操作达到的。换言之,每次的优化将会有某个点v的最短路径估计值d[v]变小。所以算法的执行会使d越来越小。由于我们假定图中不存在负权回路,所以每个结点都有最短路径值。因此,算法不会无限执行下去,随着 d值的逐渐变小,直到到达最短路径值时,算法结束,这时的最短路径估计值就是对应结点的最短路径值





int i,visit[N],cur;

memset(pre,-1,sizeof(pre));

memset(visit,0,sizeof(visit));

for(i=0;i<=n+1;i++)

dis[i]=inf;

queue<int>q;

dis[0]=0;

q.push(0);

visit[0]=1;

while(!q.empty()) {

       cur=q.front();

  q.pop();

  for(i=head[cur];i!=-1;i=bian[i].next) {//因为0是在建所有有效边之后故将所有的边都依次加入

 int  v=bian[i].v;

  if(bian[i].f&&dis[v]>dis[cur]+bian[i].c) {//加了点cur之后进行路径松弛

  dis[v]=dis[cur]+bian[i].c;

  pre[v]=i;//记录当前点连接的边的下标

  if(visit[v]==0) {//dis[v]已经有所改变如果不在队列里就把它放到队尾

  visit[v]=1;

  q.push(v);

  }

  }

  }

  visit[cur]=0;

  }

if(dis[t]==inf)

return 0;

return  1;

}

void cou(int t) {

int i,j;

i=pre[t];//连接t的边进而可以得出连接t的点

while(i!=-1) {

j=i^1;

bian[i].f--;

bian[j].f++;

sum+=bian[i].c;

i=pre[bian[i].u];//bian[i].u连接的边

}

}

int main() {

int m,a,b,c;

while(scanf("%d%d",&n,&m)!=EOF) {

yong=0;

memset(head,-1,sizeof(head));

while(m--) {

scanf("%d%d%d",&a,&b,&c);

Add(a,b,c,1);

Add(b,a,c,1);

}

Add(0,1,0,2);

Add(n,n+1,0,2);

sum=0;

while(spfa(0,n+1))  {

 cou(n+1);

}

printf("%d\n",sum);

}

return 0;

}

poj 2135最小费用最大流的更多相关文章

  1. POJ 2135 最小费用最大流 入门题

    Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 19207   Accepted: 7441 Descri ...

  2. POJ 2135 最小费用最大流

    题目链接 Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18961   Accepted: 7326 D ...

  3. poj 3422(最小费用最大流)

    题目链接:http://poj.org/problem?id=3422 思路:求从起点到终点走k次获得的最大值,最小费用最大流的应用:将点权转化为边权,需要拆点,边容量为1,费用为该点的点权,表示该点 ...

  4. POJ 2516 最小费用最大流

    每一种货物都是独立的,分成k次最小费用最大流即可! 1: /** 2: 因为e ==0 所以 pe[v] pe[v]^1 是两条相对应的边 3: E[pe[v]].c -= aug; E[pe[v]^ ...

  5. POJ - 2195 最小费用最大流

    题意:每个人到每个房子一一对应,费用为曼哈顿距离,求最小的费用 题解:单源点汇点最小费用最大流,每个人和房子对于建边 #include<map> #include<set> # ...

  6. poj 2195 最小费用最大流模板

    /*Source Code Problem: 2195 User: HEU_daoguang Memory: 1172K Time: 94MS Language: G++ Result: Accept ...

  7. poj 3680(最小费用最大流)

    题目链接:http://poj.org/problem?id=3680 思路:因为N<=200,而区间范围为[1,100000],因此需要离散化,去重,然后就是建图了相连两点连边,容量为k,费用 ...

  8. POJ 2315 最小费用最大流

    从1走到N然后从N走回来的最短路程是多少? 转换为费用流来建模. 1: /** 2: 因为e ==0 所以 pe[v] pe[v]^1 是两条相对应的边 3: E[pe[v]].c -= aug; E ...

  9. POJ 2135 Farm Tour (最小费用最大流模板)

    题目大意: 给你一个n个农场,有m条道路,起点是1号农场,终点是n号农场,现在要求从1走到n,再从n走到1,要求不走重复路径,求最短路径长度. 算法讨论: 最小费用最大流.我们可以这样建模:既然要求不 ...

随机推荐

  1. python re的使用

    re 正则表达式操作  本模块提供了类似于Perl的正则表达式匹配操作.要匹配的模式和字符串可以是Unicode字符串以及8位字符串. 正则表达式使用反斜杠字符('\')来表示特殊的形式或者来允许使用 ...

  2. JavaScript编程艺术-第10章-10.1-动画

    10.1—最简单的动画 ***代码亲测可用*** 动画:让元素位置随着时间而不断地发生变化 HTML: <!DOCTYPE HTML> <html> <head> ...

  3. linux 定义变量 ,添加变量值

    1.设置值$name=test2. 输出变量的值 echo $echo $name3. 增加变量内容PATH=$PATH:/home/bin/testPATH="$PATH":/h ...

  4. [Usaco2018 Open]Milking Order

    Description Farmer John的N头奶牛(1≤N≤10^5),仍然编号为1-N,正好闲得发慌.因此,她们发展了一个与Farmer John每天早上为她们挤牛奶的时候的排队顺序相关的复杂 ...

  5. AOP面向方面编程---postsharp

    PostSharp是一个用于在.NET平台上实现AOP(Aspect-Oriented Programming,面向方面编程)的框架,现通过简单的示例代码来演示如何使用postsharp. 1.新建一 ...

  6. C# 文件操作(摘抄)

    ——选自<c# 编程兵书>第11章 张志强 胡君 编著 11 文件操作概述 11.1 驱动器 在Windows操作系统中,存储介质统称为驱动器,硬盘由于可以划分为多个区域,每一个区域称为一 ...

  7. 410 Split Array Largest Sum 分割数组的最大值

    给定一个非负整数数组和一个整数 m,你需要将这个数组分成 m 个非空的连续子数组.设计一个算法使得这 m 个子数组各自和的最大值最小.注意:数组长度 n 满足以下条件:    1 ≤ n ≤ 1000 ...

  8. 构建一个.net的干货类库,以便于快速的开发 - 加密

    在开发程序的时候,加密是一个程序一个必须的功能,基本上任何程序都会用到加密,而不同的加密方式又适应不同需求,有些加密是不可逆的,最常见是用于用户密码的加密,因为很多时候程序里面不该显示出用户的明文密码 ...

  9. web开发----jsp中通用模版的引用 include的用法

    1.静态引入的示例 通过对两种用法的了解之后  我们现在 使用静态引入 因为上述原因  我的模版页中 只有div  不会有 path等定义  也不会有html标签 如下: 我的header.jsp 全 ...

  10. 重新学习Java——对象和类(一)

    之前通过记笔记的方法,对于<Java核心技术>这本书的前一章进行了重新的复习,感觉效果很好,比单独看书带来了更好的复习效果,了解了很多以前不是很注意的一些细节,但是在一些自己较为熟悉的地方 ...