最小费用最大流
来源:互联网 发布:蘑菇街秒杀软件 编辑:程序博客网 时间:2024/06/05 10:15
上周末打了两场网络赛,对于网络流的应用有了更深的体会【简单来讲就是还不懂得怎么自己写,就只是好像懂了一丢丢要怎么用】。把kuangbin大佬的模板再手敲一遍加上自己的注释。
//最小费用最大流
#include<cstdio>#include<cstring>#include<queue>#include<algorithm>#include<set>#include<map>using namespace std;const int maxn = 1e4;const int maxm = 1e5;const int inf = 0x3f3f3f3f;struct Edge{ int to,next,cap,flow,cost;}edge[maxm];int head[maxn],tol;int pre[maxn],dis[maxn];bool vis[maxn];int N; //节点个数,编号0->N-1 !全局变量 需要init赋值或主函数改变void init(int n){ N=n; tol = 0; memset(head,-1,sizeof(head));}void addedge(int u,int v,int cap,int cost) //边起点,终点,流量,费用{ edge[tol].to = v; edge[tol].cap = cap; edge[tol].cost = cost; edge[tol].flow = 0; edge[tol].next = head[u]; head[u] = tol++; edge[tol].to = u; edge[tol].cap = 0; edge[tol].cost = -cost; edge[tol].flow = 0; edge[tol].next = head[v]; head[v] = tol++;}bool spfa(int s,int t) //单源最短路径算法 可判断负环{ queue<int >q; for(int i=0;i<N;i++) { dis[i] = inf; vis[i] = false; pre[i] = -1; } dis[s] = 0; vis[s] = true; q.push(s); while(!q.empty()) { int u = q.front(); q.pop(); vis[u] = false; for(int i=head[u];i!=-1;i=edge[i].next) { int v= edge[i].to; if(edge[i].cap>edge[i].flow && dis[v]>dis[u]+edge[i].cost) { dis[v] = dis[u] + edge[i].cost; pre[v] = i; if(!vis[v]) { vis[v] = true; q.push(v); } } } } if(pre[t]==-1) return false; else return true;}int MCMF(int s,int t,int &cost) //MinCostMaxFlow 返回最大流,cost存最小费用{ int flow = 0; cost = 0; while(spfa(s,t)) { int Min = inf; for(int i= pre[t];i!=-1;i=pre[edge[i^1].to]) { if(Min>edge[i].cap-edge[i].flow) Min=edge[i].cap-edge[i].flow; } for(int i= pre[t];i!=-1;i=pre[edge[i^1].to) { edge[i].flow += Min; edge[i^1].flow -=Min; cost += edge[i].cost*Min; } flow += Min; } return flow;}
最小费用最大流属于网络流的一种基本算法,上周末的应用中,一道是滑雪求最长路径(滑雪只能从高到低,所以是有向路),一道是在n个城市中辗转买、卖书的问题(中间没有多次买卖,choose two cities to buy and sell)。两道题的共同特点是n个点相互之间有路,不管是不是有向的,然后我们要找到最符合要求的一种方式。两道题中我们都可以额外添加两个点作为入点和汇点,用流量来限制通过每条路、每个点的次数,用费用来体现两点之间的【贡献】。在滑雪的问题中,因为题目中要求每个点只能经过一次(流量限制的是每条路经过的次数),所以我们可以把每个点拆成两个点所连通的路,并且把这条路的流量设置为1。两道题中,所求的其实是最大费用最大流的问题(滑雪路径最长,赚的钱最多)。我们可以将每条路的花费设置成负数,就可以了。有向边和无向边的区别我们可以建两个有向边。end
阅读全文
0 0
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 【最小费用最大流】
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- Java 内存模型及GC原理
- 无需第三方软件实现Mac支持ntfs读写的最简单操作
- ReactNative中SectionList实现条目GridView效果
- GitChat · 架构 | 为什么微服务实施那么难?如何高效推进微服务架构演进
- 计算机应用
- 最小费用最大流
- 产品原型的重要性
- phpcms V9 get 实现前台搜索结果分页
- if结构
- 简谈JAVA基础--数据类型
- res下的anim和animator文件夹
- leetcode 674. Longest Continuous Increasing Subsequence
- Libjpeg搭建手记
- android webview 加载图片一直显示正在加载中