最小费用最大流模板
来源:互联网 发布:天文搜星算法 编辑:程序博客网 时间:2024/06/05 18:00
最小费用最大流一般用邻接表来实现,因为邻接矩阵不能处理平行边等等;而一条有向边是要储存两条信息,无向图的话要拆成两条有向边处理,相当于变为4条边,这也是邻接矩阵不能做到的
然后最小费用最大流的原理就不讲了,讲一下实现的要注意的问题和一些技巧
1.用结构体数组来保存边,最好从下标0开始保存不要从下标1开始保存,因为增广的时候需要用到位运算,从下标1保存不利于位运算
2.记录路径:如果是邻接矩阵记录前驱p[v]=u,表示一条边u—>v,u就是v的前驱
所以找出整条路径就是一个循环 for(u=t; u!=s; u=p[u])
邻接表p[v]=i; //i表示的是第i条边,那么它的前驱应该是e[i].u,即在这条边的信息内部
所以找出整条路径是 for(i=p[t]; i!=-1; i=p[e[i].u]) //i表示的是边的标号
3.最小费用最大流:
I.在还能增流的条件下,以单位费用作为权去求源点到汇点最短路并且需要记录路径,但记住不要改变流量,改变流量是增广的时候做的,因为单位费用可能有负值所以用spfa。(spfa算法)
II.如果能得到到汇点的最短路,说明还没到达最小费用最大流,那么就沿刚才记录的路径返回,找出最小残余流量
III.增广:即再沿路径返回一次,添加残余流量,反向则减少残余流量
IV.更新最大流,和最小费用 即F+=min; C+=d[t]*min; //min是本次的最小参与流量
#define MAXN 1003#define MAXM 40004using namespace std; const int INF = 0x3f3f3f3f;struct EDGE{ int to, cap, next, flow, cost;}edge[MAXM];int q[MAXN], head[MAXN], tol;int pre[MAXN], dis[MAXN];bool vis[MAXN];int n, m;void init(){ tol = 0; memset(head, -1, sizeof(head));}void addEdge(int u, int v, int cap, int cost){ edge[tol].cap = cap; edge[tol].cost = cost; edge[tol].flow = 0; edge[tol].next = head[u]; edge[tol].to = v; head[u] = tol++; edge[tol].cap = 0; edge[tol].cost = -cost; edge[tol].flow = 0; edge[tol].next = head[v]; edge[tol].to = u; head[v] = tol++;}bool spfa(int st, int en){ int rear = 0, front = 0; for (int i = st; i <= en+1; i++){ dis[i] = INF; vis[i] = false; pre[i] = -1; } dis[st] = 0; vis[st] = true; q[front++] = st; while(rear < front){ int u = q[rear++]; vis[u] = false; for (int e = head[u]; e != -1; e = edge[e].next){ int v = edge[e].to; if (edge[e].cap > edge[e].flow && dis[v] > dis[u]+edge[e].cost){ dis[v] = dis[u] + edge[e].cost; pre[v] = e; if (!vis[v]){ vis[v] = true; q[front++] = v; } } } } return pre[en] != -1;}int minCostMaxflow(int st, int en, int &cost){ int flow = 0; while(spfa(st, en)){ int Min = INF; for (int i = pre[en]; i != -1; i = pre[edge[i^1].to]){ Min = Min > (edge[i].cap-edge[i].flow) ? (edge[i].cap-edge[i].flow) : Min; } for (int i = pre[en]; i != -1; i = pre[edge[i^1].to]){ edge[i].flow += Min; edge[i^1].flow -= Min; cost += Min*edge[i].cost; } } return flow;}
poj 2135
最小费用最大流模板题
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#define MAXN 1003#define MAXM 40004using namespace std; const int INF = 0x3f3f3f3f;struct EDGE{ int to, cap, next, flow, cost;}edge[MAXM];int q[1000000], head[MAXN], tol;int pre[MAXN], dis[MAXN];bool vis[MAXN];int n, m;void init(){ tol = 0; memset(head, -1, sizeof(head));}void addEdge(int u, int v, int cap, int cost){ edge[tol].cap = cap; edge[tol].cost = cost; edge[tol].flow = 0; edge[tol].next = head[u]; edge[tol].to = v; head[u] = tol++; edge[tol].cap = 0; edge[tol].cost = -cost; edge[tol].flow = 0; edge[tol].next = head[v]; edge[tol].to = u; head[v] = tol++;}bool spfa(int st, int en){ int rear = 0, front = 0; for (int i = st; i <= en+1; i++){ dis[i] = INF; vis[i] = false; pre[i] = -1; } dis[st] = 0; vis[st] = true; q[front++] = st; while(rear < front){ int u = q[rear++]; vis[u] = false; for (int e = head[u]; e != -1; e = edge[e].next){ int v = edge[e].to; if (edge[e].cap > edge[e].flow && dis[v] > dis[u]+edge[e].cost){ dis[v] = dis[u] + edge[e].cost; pre[v] = e; if (!vis[v]){ vis[v] = true; q[front++] = v; } } } } return pre[en] != -1;}int minCostMaxflow(int st, int en, int &cost){ int flow = 0; while(spfa(st, en)){ int Min = INF; for (int i = pre[en]; i != -1; i = pre[edge[i^1].to]){ Min = Min > (edge[i].cap-edge[i].flow) ? (edge[i].cap-edge[i].flow) : Min; } for (int i = pre[en]; i != -1; i = pre[edge[i^1].to]){ edge[i].flow += Min; edge[i^1].flow -= Min; } cost += dis[en] * Min; } return flow;}int main(){ int i, j, k, cost, u, v; scanf("%d%d", &n, &m); init(); for (i = 0; i < m; i++){ scanf("%d%d%d", &u, &v, &cost); addEdge(u, v, 1, cost); addEdge(v, u, 1, cost); } addEdge(0, 1, 2, 0); addEdge(n, n+1, 2, 0); cost = 0; minCostMaxflow(0, n+1, cost); printf("%d\n", cost); return 0;}
0 0
- 模板[最小费用最大流]
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流,模板
- 最小费用最大流模板
- 最小费用最大流 模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- 最小费用最大流模板
- SQL SERVER 局部变量
- JAVA设计模式(11):结构型-装饰模式(Decorator)
- android native 与h5 交互技巧
- 赋值运算符函数
- Python处理多个客户端连接---派生服务器
- 最小费用最大流模板
- SQL SERVER 全局变量
- Android 四种常用的监听器
- JVM学习
- VMware12 + redhat7 + windows7网络配置
- 卷积神经网络
- ReactiveCocoa操作方法(映射,组合)
- 问题解决了,可是为什么呢?could not find the main class.program will exitmain
- C语言任意交换两种类型变量