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;
}

 

 

posted on 2010-11-17 10:07  ltang  阅读(2161)  评论(0编辑  收藏  举报

导航