【第22期】观点:IT 行业加班,到底有没有价值?

poj 2135最小费用最大流

原创 2013年12月06日 00:18:51

最小费用最大流问题是经济学和管理学中的一类典型问题。在一个网络中每段路径都有“容量”和“费用”两个限制的条件下,此类问题的研究试图寻找出:流量从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 Farm Tour(最小费用最大流 模板题)

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

POJ 2175 最小费用最大流之消圈 根据已有流量建立残留网络

这道题看似是建图十分简单,实则用裸的最小费用最大流必然会超时,用zkw费用流也会超时。 所以必须看清题意,题目要求只要比当前方案好就行,没说要最好。 那么根据定理,一个费用流是最小费用流的充要条件是这个费用流的残量网络没有负费用圈。对于这个定理,如果不明白可以画一画。 <span sty...

程序员升职加薪指南!还缺一个“证”!

CSDN出品,立即查看!

最小费用最大流问题----poj 2135

最小费用最大流 网络流的费用: 在实际应用中,与网络流有关的问题,不仅涉及流量,而且还有费用的因素。网络的每一条边(v,w)除了给定容量cap(v,w)外,还定义了一个单位流量费用cost(v,w)...

POJ 2195 Going Home 最小费用最大流 or KM算法

题目大意是一张地图中,有n个人要走回n个房子里,然后人只能横着或竖着走一格,求他们回家的距离总和最短。 这道题看起来是个最优匹配问题,用KM或者最小费用最大流做 首先把每个人与每个房子之间的距离求出来 然后就是套用模板了 #include &lt;iostream&gt;...

POJ 2135 Farm Tour 最小费用最大流 -

题目地址:http://poj.org/problem?id=2135 由于去和回来可以看成:2条从1到n的不同的路。所以转化成求从1到n的两条不同的路。 建立一个源点,连接1号景点,无费用,...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)