最小费用网络流
来源:互联网 发布:义乌网络歌手招聘 编辑:程序博客网 时间:2024/04/29 04:37
思路:
反复用spfa算法做源到汇的最短路进行增广,边权值为边上单位费用。反向边上的单位费用是负的。
直到无法增广,即为找到最小费用最大流。
成立原因:每次增广时,每增加1个流量,所增加的费用都是最小的。
因为有负权边(取消流的时候产生的),所以不能用迪杰斯特拉算法求最短路。
因为增广的时候要知道上个节点,这不难,但还要快速的知道其反向边是哪个,这个就比较麻烦
而如果用邻接矩阵的话又太占空间,所以用邻接表,方法如下:
给每条边编号,一个边和其的反向边放在一起,所以编号为i的边的反向边的编号是i^1
#include<iostream>#include<queue>#include<cstring>#include<cstdio>using namespace std;const int maxn=1000+5;const int INF=1000000000;struct Edge{int from,to,flow,weight;Edge(int f,int t,int fl,int w):from(f),to(t),flow(fl),weight(w){}};vector<Edge> edges; vector<vector<int> > G(maxn);bool inq[maxn]; //判断是否在队列里 int dist[maxn];int prev[maxn]; //记录路径 void AddEdge(int u,int v,int fl,int w){edges.push_back(Edge(u,v,fl,w));G[u].push_back(edges.size()-1); //保存该边的编号 }bool Spfa(int s,int t){memset(inq,false,sizeof(inq));fill(dist,dist+t+2,INF);memset(prev,-1,sizeof(prev));queue<int> Q;dist[s]=0;inq[s]=true; Q.push(s);while(!Q.empty()){int u=Q.front(); Q.pop();inq[u]=false;for(int i=0;i<G[u].size();i++){int v=edges[G[u][i]].to, w=edges[G[u][i]].weight, flow=edges[G[u][i]].flow;if(flow>0&&dist[v]>dist[u]+w) //要在flow>0情况下 {dist[v]=dist[u]+w;prev[v]=G[u][i];if(!inq[v]) Q.push(v),inq[v]=true;}}}return dist[t]!=INF;}int solve(int n) //输出最大流的最小代价 {int s=0,t=n+1;int Mindist=0; //最大流的最小代价 int MaxFlow=0; //最大流 AddEdge(s,1,2,0);AddEdge(1,s,0,0);AddEdge(n,t,2,0);AddEdge(t,n,0,0);while(Spfa(s,t)) //当存在最短路 {int MinFlow=INF; Mindist+=dist[t];int v=t;while(v!=s){ //计算途中最小流 Edge e=edges[prev[v]];int u=e.from;MinFlow=min(MinFlow,e.flow);v=u;}MaxFlow+=MinFlow;v=t;while(v!=s){int u=edges[prev[v]].from;edges[prev[v]].flow-=MinFlow; edges[prev[v]^1].flow+=MinFlow; edges[prev[v]^1].weight=-edges[prev[v]].weight; //反向边的cost设为负的 v=u;}}return Mindist;}int main(){int m,n,u,v,w;while(scanf("%d%d",&n,&m)!=EOF){edges.clear();for(int i=0;i<=n+1;i++) G[i].clear();for(int i=0;i<m;i++){scanf("%d%d%d",&u,&v,&w);AddEdge(u,v,1,w); //i 是u->v边 AddEdge(v,u,1,w); //i^1是v->u边 }cout<<solve(n)<<endl;} return 0;}
0 0
- 最小费用网络流
- 最小费用网络流,不含重边
- 网络最大流和最小费用流
- 网络最大流和最小费用流
- 【最大流+最小费用流】网络扩容
- 网络流 最小费用最大流问题
- 网络流 最小费用最大流
- 网络流-最小费用最大流
- 网络流问题-最小费用最大流
- 网络流-最小费用最大流
- 网络流--最小费用最大流
- 网络费用流-最小k路径覆盖
- [网络流24题] 17 运输问题(网络费用流量,最小费用最大流)
- 网络流(最大流和最小费用流)
- 网络流-最大流&最小费用最大流
- 【ZJOI2010】【最大流】【最小费用最大流】网络扩容
- [BZOJ1834][ZJOI2010][最大流][最小费用最大流]网络扩容
- HDU 3488Tour(网络流之最小费用流)
- 深入浅出JMS(四)--Spring和ActiveMQ整合的完整实例
- HDU 1856More is better
- GCC在C语言中内嵌汇编 asm __volatile__
- 无限循环的Viewpager
- 简单又好看的扁平化按钮。
- 最小费用网络流
- Tomcat--严重: StandardServer.await: create[8005]
- HDU 1272小希的迷宫
- 我的第一篇博客
- 子窗口的title与句柄的相互转换
- web页面通过JS显示当前日期
- (笔记)Linux续
- POJ 3114 Countries in War(强连通分量 最短路)
- jQuery.extend函数