最小费用最大流(板子)
来源:互联网 发布:网络直播举报 编辑:程序博客网 时间:2024/06/06 13:05
写最小费用最大流的时候比较容易忘的是添加一条边的费用时忘记将反向边的费用置为原来边的相反数。
这一点要特别注意。
邻接矩阵版本
//************************************************************//最小费用最大流算法//SPFA求最短路//邻接矩阵形式//初始化:cap:容量,没有边为0//cost:耗费,对称形式,没有边的也为0//c是最小费用//f是最大流//*******************************************************const int MAXN=500;const int INF=0x3fffffff;int cap[MAXN][MAXN];//容量,没有边为0int flow[MAXN][MAXN];//耗费矩阵是对称的,有i到j的费用,则j到i的费用为其相反数int cost[MAXN][MAXN];int n;//顶点数目0~n-1int f;//最大流int c;//最小费用int start,end;//源点和汇点bool vis[MAXN];//在队列标志int que[MAXN];int pre[MAXN];int dist[MAXN];//s-t路径最小耗费bool SPFA(){ int front=0,rear=0; for(int u=0;u<=n;u++) { if(u==start) { que[rear++]=u; dist[u]=0; vis[u]=true; } else { dist[u]=INF; vis[u]=false; } } while(front!=rear) { int u=que[front++]; vis[u]=false; if(front>=MAXN)front=0; for(int v=0;v<=n;v++) { if(cap[u][v]>flow[u][v]&&dist[v]>dist[u]+cost[u][v]) { dist[v]=dist[u]+cost[u][v]; pre[v]=u; if(!vis[v]) { vis[v]=true; que[rear++]=v; if(rear>=MAXN)rear=0; } } } } if(dist[end]>=INF)return false; return true;}void minCostMaxflow(){ memset(flow,0,sizeof(flow)); c=f=0; while(SPFA()) { int Min=INF; for(int u=end;u!=start;u=pre[u]) Min=min(Min,cap[pre[u]][u]-flow[pre[u]][u]); for(int u=end;u!=start;u=pre[u]) { flow[pre[u]][u]+=Min; flow[u][pre[u]]-=Min; } c+=dist[end]*Min; f+=Min; }}
邻接表版本
#include <stdio.h>#include <algorithm>#include <string.h>#include <iostream>#include <string>#include <queue>using namespace std;const int MAXN = 10000;const int MAXM = 100000;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-1void 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;}//返回的是最大流,cost存的是最小费用int minCostMaxflow(int s,int t,int &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;}
0 0
- 最小费用最大流(板子)
- luogu3381【模板】最小费用最大流(zkw费用流板子)
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 【最小费用最大流】
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- 最小费用最大流
- My_String类案例(构造、析构、重载'=' '[]' '<<' '==' '!=' '>' '<' '>>' 运算、操作符以及其他技巧)(重载完结)
- JavaScript中如何严格的判断NaN
- java中实现数组转化为字符串
- PAT(B).1028. 人口普查(20)
- 黑盒测试的方法
- 最小费用最大流(板子)
- stm32控制2.4G芯片的应用
- Android 实现多个输入框的对话框
- HDU 1875 畅通工程再续 有限制的最小生成树
- 两个链表的第一个公共结点
- 混合开发中遇到的上拉刷新,下拉加载的问题
- 代码整洁—什么是好代码
- Lua string.sub截取UTF8 中英混合字符
- JTabel 单元格中加入日期选择器DatePicker