dinic算法
思想:
a)原图中的点按照到到源的距离分“层”,只保留不同层之间的边的图
b)根据残量网络计算层次图
c)在层次图中使用DFS 进行增广直到不存在增广路
d)重复以上步骤直到无法增广
1-递归实现,效率略低
#define INF 1e8
#define MAX_VECT 205
#define MAX_EDGE 22000
/************************************************************************/
/* Name: dinic
/* Description: Find the max flow of the network from start to
end point
/* Variable Description: to[] - end point of the current edge
next[] - the next edge which also comes from
the same point as current edge
cap[] - the capability of the current edge
v[] - the first edge index which comes from the
the current point
d[] - the layer number of current point
/************************************************************************/
int to[MAX_EDGE], next[MAX_EDGE], cap[MAX_EDGE], m;
int v[MAX_VECT], d[MAX_VECT], queue[MAX_VECT], n;
int S, T;
inline void single_insert(int _u, int _v, int var)
{
to[m] = _v;
cap[m] = var;
next[m] = v[_u];
v[_u] = m++;
}
void insert(int from, int to, int cap)
{
single_insert(from, to, cap);
single_insert(to, from, 0);
}
bool bfs_initial()
{
memset(d, -1, sizeof(d));
int bg, ed, x, y;
bg = ed = d[S] = 0;
queue[ed++] = S;
while (bg < ed)
{
x = queue[bg++];
for (int i = v[x]; i+1; i = next[i])
{
y = to[i];
if (cap[i] && d[y] == -1)
{
d[y] = d[x] + 1;
if (y == T) return true;
queue[ed++] = y;
}
}
}
return false;
}
int Find(int x, int low = INF)
{
if (x == T) return low;
int ret, y, ans = 0;
for (int i = v[x]; (i+1) && low; i = next[i])
{
y = to[i];
if (cap[i] && d[y] == d[x] + 1 && (ret = Find(y, min(low, cap[i]))))
{
cap[i] -= ret;
cap[i^1] += ret;
low -= ret;
ans += ret;
}
}
return ans;
}
int dinic()
{
int ans = 0;
while (bfs_initial())
ans += Find(S);
return ans;
}
2- 非递归实现,效率较高
int dinic()
{
int ans = 0;
while(bfs_initial())
{
int edge, x, y, back, iter = 1;
while(iter)
{
x = (iter == 1) ? S : to[queue[iter - 1]];
if (x == T)
{
int minE, minCap = INF;
for (int i = 1; i < iter; i++)
{
edge = queue[i];
if (cap[edge] < minCap)
{
minCap = cap[edge];
back = i;
}
}
for (int i = 1; i < iter; i++)
{
edge = queue[i];
cap[edge] -= minCap;
cap[edge ^ 1] += minCap;
}
ans += minCap;
iter = back;
}
else
{
for (edge = v[x]; edge + 1; edge = next[edge])
{
y = to[edge];
if (cap[edge] && d[y] == d[x] + 1)
break;
}
if (edge+1)
queue[iter++] = edge;
else
{
d[x] = -1;
iter--;
}
}
}
}
return ans;
}