这是我们运筹学的大作业~贴的代码可以直接在vs上跑,也是我们最终的代码,数据矩阵也在里面,具体的题目、解释什么的,等我写完课程论文把论文贴上来…
借鉴的代码链接: link.
#include "stdio.h" #include #include #include #include #include #include #include #include #include #include #define max 5000 #define MAXN 5050 #define INF 0x3f3f3f3f using namespace std; int n, m, s, t; int u, v, c, w; int maxFlow, minCost; struct Edge { int from, to, flow, cap, cost; }; bool vis[MAXN]; int p[MAXN], a[MAXN], d[MAXN],route[MAXN]; vector g[MAXN]; vector edges; void init(int n) { for (int i = 0; i <= n; i++) g[i].clear(); edges.clear(); } void addedge(int from, int to, int cap, int cost) { Edge temp1 = { from, to, 0, cap, cost }; Edge temp2 = { to, from, 0, 0, -cost };//允许反向增广 edges.push_back(temp1); edges.push_back(temp2); //加进来两条边 int len = edges.size(); g[from].push_back(len - 2); g[to].push_back(len - 1); } //贝尔曼-福特算法实现 bool bellmanford(int s, int t) { for (int i = 0; i < MAXN; i++) { d[i] = INF; route[i] = 0; } d[s] = 0; memset(vis, false, sizeof(vis)); memset(p, -1, sizeof(p)); p[s] = -1; a[s] = INF; queue que; que.push(s); vis[s] = true; while (!que.empty()) { int u = que.front(); que.pop(); vis[u] = false; for (int i = 0; i < g[u].size(); i++) { Edge& e = edges[g[u][i]]; if (e.cap > e.flow && d[e.to] > d[u] + e.cost )//进行松弛,寻找最短路径也就是最小费用 { route[e.to] = e.from; d[e.to] = d[u] + e.cost; p[e.to] = g[u][i]; a[e.to] = min(a[u], e.cap - e.flow); if (!vis[e.to]) { que.push(e.to); vis[e.to] = true; } } } } if (d[t] == INF) return false; maxFlow += a[t]; minCost += d[t] * a[t]; for (int i = t; i != s; i = edges[p[i]].from) { edges[p[i]].flow += a[t]; edges[p[i] ^ 1].flow -= a[t]; } return true; } void MCMF() { while (bellmanford(s, t)) continue; cout << endl; cout << "我要开始输出结果啦!" << endl; for (int i = 0; i < 20; i = i+2) cout << edges[i].flow << " "; cout << endl; for (int i = 20; i < 40; i=i+2) cout << edges[i].flow << " "; cout << endl; for (int i = 40; i < 74; i=i+2) cout << edges[i].flow << " "; cout << endl; cout << endl; return; } int main() { cout << "节点数为:"; cin >> n; cout << "边数为:"; cin >> m; cout << "源点编号为:"; cin >> s; cout << "汇点编号为:"; cin >> t; /*int shuru[] = { 1,3,max,210, 1,4,120,185, 1,8,max,210, 1,7,120,200, 1,10,max,500, 1,9,120,410, 1,11,120,620, 1,6,max,470, 1,5,120,400, 0,1,500,0, 0,2,300,0, 2,3,max,230, 2,4,120,205, 2,8,max,210, 2,7,120,200, 2,10,max,280, 2,9,120,240, 2,11,120,350, 2,5,120,150, 2,6,max,160, 3,8,max,100, 4,7,120,80, 3,10,max,170, 4,9,120,150, 4,11,120,250, 4,5,120,135, 3,6,max,160, 5,4,120,140, 6,3,max,160, 5,7,120,270, 6,8,max,315, 5,9,120,110, 6,10,max,130, 5,11,120,130, 7,12,max,0, 8,12,max,0, 9,13,max,0, 10,13,max,0, 12,14,300,0, 13,14,400,0, 11,14,100,0, 3,4,max,0,4,3,max,0, 5,6,max,0,6,5,max,0 };*/ /*int shuru[] = { 1,3,max,210, 1,4,120,185, 1,8,max,210, 1,7,120,200, 1,10,max,500, 1,9,120,410, 1,11,120,620, 1,6,max,470, 1,5,120,400, 0,1,500,0, 0,2,300,0, 2,3,max,230, 2,4,120,205, 2,8,max,210, 2,7,120,200, 2,10,max,280, 2,9,120,240, 2,11,120,350, 2,5,120,150, 2,6,max,160, 17,8,max,100, 18,7,120,80, 17,10,max,170, 18,9,120,150, 18,11,120,250, 18,5,120,135, 17,6,max,160, 21,4,120,140, 22,3,max,160, 21,7,120,270, 22,8,max,315, 21,9,120,110, 22,10,max,130, 21,11,120,130, 7,12,max,0, 8,12,max,0, 9,13,max,0, 10,13,max,0, 12,14,300,0, 13,14,400,0, 11,14,100,0, 3,15,max,0, 4,15,max,0, 15,16,100,0, 16,17,max,0, 16,18,max,0, 5,19,max,0, 6,19,max,0, 19,20,80,0, 20,21,max,0, 20,22,max,0 };*/ //简化版 不带容量限制 /*int shuru[] = { 1,3,max,210, 1,3,120,185, 1,7,max,210, 1,7,120,200, 1,9,max,500, 1,9,120,410, 1,11,120,620, 1,5,max,470, 1,5,120,400, 0,1,500,0, 0,2,300,0, 2,3,max,230, 2,3,120,205, 2,7,max,210, 2,7,120,200, 2,9,max,280, 2,9,120,240, 2,11,120,350, 2,5,120,150, 2,5,max,160, 3,7,max,100, 3,7,120,80, 3,9,max,170, 3,9,120,150, 3,11,120,250, 3,5,120,135, 3,5,max,160, 5,3,120,140, 5,3,max,160, 5,7,120,270, 5,7,max,315, 5,9,120,110, 5,9,max,130, 5,11,120,130, 7,14,300,0, 9,14,400,0, 11,14,100,0, };*/ int shuru[] = { 1,3,max,210, 1,3,120,185, 1,7,max,210, 1,7,120,200, 1,9,max,500, 1,9,120,410, 1,11,120,620, 1,5,max,470, 1,5,120,400, 0,1,500,0, 0,2,300,0, 2,3,max,230, 2,3,120,205, 2,7,max,210, 2,7,120,200, 2,9,max,280, 2,9,120,240, 2,11,120,350, 2,5,120,150, 2,5,max,160, 4,7,max,100, 4,7,120,80, 4,9,max,170, 4,9,120,150, 4,11,120,250, 4,5,120,135, 4,5,max,160, 6,3,120,140, 6,3,max,160, 6,7,120,270, 6,7,max,315, 6,9,120,110, 6,9,max,130, 6,11,120,130, 7,14,300,0, 9,14,400,0, 11,14,100,0, 3,4,100,0, 5,6,80,0 }; int i = 0; while (m--) { u = shuru[i]; i = i + 1; v = shuru[i]; i = i + 1; c = shuru[i]; i = i + 1; w = shuru[i]; i = i + 1; addedge(u, v, c, w); } MCMF(); cout << endl; cout << "最大流为:" << maxFlow << endl; cout << "最小费用为" << minCost << endl; cout << endl; system("pause"); return 0; }
大多数最小费用最大流的代码注释都很少,我初学的时候反正是真的看不太懂。等期末考试完了,有时间的话我再来认真写写注释,也算是记录学习过程吧~