网络流--最小费用最大流MCMF算法
来源:互联网 发布:仙侠世界大网络下载 编辑:程序博客网 时间:2024/06/05 07:28
转载:http://www.cnblogs.com/Missa/archive/2013/04/19/3030512.html
在一个网络中每段路径都有“容量”和“费用”两个限制的条件下,此类问题的研究试图寻找出:流量从A到B,如何选择路径、分配经过路径的流量,可以达到所用的费用最小的要求。如n辆卡车要运送物品,从A地到B地。由于每条路段都有不同的路费要缴纳,每条路能容纳的车的数量有限制,最小费用最大流问题指如何分配卡车的出发路径可以达到费用最低,物品又能全部送到。
1 //最小费用最大流模版.求最大费用最大流建图时把费用取负即可。 2 //无向边转换成有向边时需要拆分成两条有向边。即两次加边。 3 const int maxn = 1010; 4 const int maxm = 1000200; 5 const int inf = 1000000000; 6 struct Edge 7 { 8 int v, cap, cost, next; 9 }p[maxm << 1];10 int e, sumFlow, n, m, st, en;11 int head[maxn], dis[maxn], pre[maxn];12 bool vis[maxn];13 void init()14 {15 e=0;16 memset(head,-1,sizeof(head));17 }18 void addEdge(int u,int v,int cap,int cost)19 {20 p[e].v = v; p[e].cap = cap; p[e].cost = cost;21 p[e].next = head[u]; head[u] = e++;22 p[e].v = u; p[e].cap = 0; p[e].cost = - cost;23 p[e].next = head[v]; head[v] = e++;24 }25 bool spfa(int s,int t, int n)26 {27 int u,v;28 queue<int>q;29 memset(vis,false,sizeof(vis));30 memset(pre,-1,sizeof(pre));31 for(int i = 0; i <= n; ++i) 32 dis[i] = inf;33 vis[s] = true;34 dis[s] = 0;35 q.push(s);36 while(!q.empty())37 {38 u = q.front();39 q.pop();40 vis[u] = false;41 for(int i = head[u]; i != -1; i = p[i].next)42 {43 v = p[i].v;44 if(p[i].cap && dis[v] > dis[u] + p[i].cost)45 {46 dis[v] = dis[u] + p[i].cost;47 pre[v] = i;48 if(!vis[v])49 {50 q.push(v);51 vis[v]=true;52 }53 }54 }55 }56 if(dis[t] == inf) 57 return false;58 return true;59 }60 int MCMF(int s,int t,int n)61 {62 int flow = 0; // 总流量63 int minflow, mincost;64 mincost=0;65 while(spfa(s,t,n))66 {67 minflow = inf + 1;68 for(int i = pre[t]; i != -1; i = pre[p[i^1].v])69 if(p[i].cap < minflow)70 minflow = p[i].cap;71 flow += minflow;72 for(int i=pre[t];i!=-1;i=pre[p[i^1].v])73 {74 p[i].cap -= minflow;75 p[i^1].cap += minflow;76 }77 mincost += dis[t] * minflow;78 }79 sumFlow = flow; // 最大流80 return mincost;81 }
如果理解了最大流连续增广路算法的思维, 理解这个算法还是很简单的。
结构体存储信息:
分别为边的起点、终点、容量、当前流量、费用、下一条边的编号。
算法实现过程:
1,每次查找是否 存在源点到汇点的可增广路径,并用pre[ i ]记录路径上到达点i 的 边 的编号。这里的路径指的是 —— 源点到汇点的最短路(边权为费用) 且 路径上所有边都不能满流;
2,若存在这样的路径,从汇点沿着pre数组向前找,找到该路径上可以增广的流量Min(当然是所有边中剩余流量最小的)。再从汇点遍历一次,正向边增加流量Min,反向边减少Min,总费用累加Min * edge[i].cost,总流量累加Min。
模板:
建图没有写,毕竟图论建图没有模板 o(╯□╰)o
阅读全文
0 0
- 网络流--最小费用最大流MCMF算法
- 最小费用最大流MCMF算法
- 【图】最小费用最大流MCMF
- [存模板]最小费用最大流 MCMF
- 最小费用最大流---MCMF模版
- MCMF最小费用最大流模板
- 图论--最小费用最大流(MCMF)
- POJ 2516 Minimum Cost 【MCMF:最小费用最大流】
- TOJ 1583: Farm Tour -- 最小费用最大流 MCMF
- POJ 2516 Minimum Cost(最小费用最大流-mcmf)
- HDU 4862 Jump(最小费用最大流-mcmf)
- POJ2195 Going Home(最小费用最大流mcmf)
- HDU5619 Jam's store(最小费用最大流 MCMF)
- HDU 4494 Teamwork(最大流-Dinic+最小费用最大流-mcmf)
- 最小费用最大流算法
- 最小费用最大流算法
- 最小费用最大流算法
- 最小费用最大流算法
- java 开发实战经典 练习题 第12章 第7题 完成系统登录程序 从命令行输入用户名和密码
- MicroSoft SQL Server Manager 通过ODBC与VS进行连接操作示例程序
- C语言实例练习
- ASP.NET Core的身份认证框架IdentityServer4(7)- 使用客户端证书控制API访问
- linux如何设置行号
- 网络流--最小费用最大流MCMF算法
- 24. Swap Nodes in Pairs
- 279. Perfect Squares (完全平方数)
- 10大深度学习架构:计算机视觉优秀从业者必备(附代码实现)
- 关于tensorboard启动问题
- STL bitset用法总结
- 用Maven创建JIfnal需要引入两个
- 使用子查询
- 【11】jQuery控制的不同方向的滑动(向左、向右滑动等)