#include<iostream>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
#define MAXFLOW 0x3f3f3f3f
int G[300][300];//用邻接矩阵存储图
bool visited[300];
int n, m;//m为顶点数,从1~m,n为边数
int Layer[300];
//计算每个点的层数,从源点到汇点路径都是从上一层顶点到下一层顶点,若不能分层,则搜索结束
bool CountLayer()
{
int layer = 0;
deque<int>q;
memset(Layer, 0xff, sizeof(Layer));
Layer[1] = 0;
q.push_back(1);
while (!q.empty())
{
int v = q.front();
q.pop_front();
for (int j = 1; j <= m; j++) {
if (G[v][j] > 0 && Layer[j] == -1) {
Layer[j] = Layer[v] + 1;
if (j == m) {
return true;
}
else q.push_back(j);
}
}
}
return false;
}
//计算最大流
int Dinic() {
int i, s;
int nMaxFlow = 0;
deque<int>q;//DFS的栈
while (CountLayer())//如果可以进行分层,说明从源点到汇点存在路径
{
q.push_back(1);//源点入栈
memset(visited, 0, sizeof(visited));
visited[1] = true;
while (!q.empty())
{
int nd = q.back();
//nd是汇点
if (nd == m) {
int nMinc = MAXFLOW;//nMinc记录路径上的最小流量
int nMinc_vs;//容量最小边的起点
for (i = 1; i < q.size(); i++) {
int vs = q[i - 1];
int ve = q[i];
if (G[vs][ve] > 0) {
if (nMinc > G[vs][ve]) {
nMinc = G[vs][ve];
nMinc_vs = vs;
}
}
}
nMaxFlow += nMinc;
for (i = 1; i < q.size(); i++) {
int vs = q[i - 1];
int ve = q[i];
G[vs][ve] -= nMinc;//修改容量边
G[ve][vs] += nMinc;//修改反向边
}
//退栈到nMinc_vs成为栈顶,以便继续dfs
while (!q.empty()&&q.back()!=nMinc_vs)
{
visited[q.back()] = 0;
q.pop_back();
}
}
//nd不是汇点
else
{
for (i = 1; i <= m; i++) {
if (G[nd][i] > 0 && Layer[i] == Layer[nd] + 1 && !visited[i]) {
visited[i] = 1;
q.push_back(i);
break;
}
}
if (i > m)
q.pop_back();//找不到下一个点,回溯
}
}
}
return nMaxFlow;
}
Dinic()模板
最新推荐文章于 2019-08-09 15:40:14 发布