这是我们运筹学的大作业~贴的代码可以直接在vs上跑,也是我们最终的代码,数据矩阵也在里面,具体的题目、解释什么的,等我写完课程论文把论文贴上来…
借鉴的代码链接: link.
#include "stdio.h"
#include <iostream>
#include <algorithm>
#include <map>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#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<int> g[MAXN];
vector<Edge> 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<int> 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;
}
大多数最小费用最大流的代码注释都很少,我初学的时候反正是真的看不太懂。等期末考试完了,有时间的话我再来认真写写注释,也算是记录学习过程吧~