第一步先用BFS给各个节点标层次。用的是到终点的距离进行标记。
从终点开始从0到终点为起点给各个点进行标记。
第二步从起点出发对给点到终点的路径。
有剩余流量并且相邻的点的距离函数比此点小1的话,探索的点x前进到相邻的点。
有剩余流量但是距离函数不符合的话把此点的距离函数标记成有剩余流量的最小数加1。
并把探索的点置为探索点x的路径上前一个点。(如果x不是起点的话)
x是起点的话则x不变。
当x为终点时把此路径上的流量加入总流量。
当起点的距离函数为结点数时终结探索过程。
当值为某个值距离函数的总数为0点时,此图不再连通。终结过程。
代码为poj1459的ISAP的代码
#include<iostream>
using namespace std;
struct Edge
{
int cap, flow;
};
Edge edges[200][200];
int size;
int visit[200], s, t;
int p[1000000], num[1000000];
int q[1000000], d[1000000];
int Count;
int BFS()
{
int i, front, tail,temp;
for(i = 0; i < size + 2 ; i++)
{
visit[i] = 0;
}
front = 0; tail = 1;
q[front] = t;
visit[t] = 1;
d[t] = 0;
num[d[t]]++;
while(front < tail)
{
temp = q[front];
front++;
for(i = 0; i < size + 2 ; i++)
{
if(!visit[i] && edges[i][temp].cap > edges[i][temp].flow)
{
q[tail] = i;
d[i] = d[temp] + 1;
num[d[i]]++;
visit[i] = 1;
tail++;
}
}
}
return visit[t];
}
int augment()
{
int a = 1000000, temp;
for(int i = 0; i < Count - 1; i++)
{
temp = edges[p[i]][p[i + 1]].cap - edges[p[i]][p[i + 1]].flow;
if(temp < a)
a = temp;
}
for(int i = 0; i < Count - 1; i++)
{
edges[p[i]][p[i + 1]].flow += a;
edges[p[i + 1]][p[i]].flow -= a;
}
// for(int i = 0; i < Count ; i++)
// {
// cout << "aaa " << p[i] << " " << a <<endl;
// }
// cout <<endl;
return a;
}
int maxFlow()
{
BFS();
int x = s,i, flow = 0, ok, min, m;
Count = 0; p[Count++] = s;
while(d[s] < size + 2 )
{
if(x == t)
{
flow += augment();
x = s; Count = 0;
p[Count++] =s;
}
ok = 0;
for(i = 0; i < size + 2 ; i++)
{
if(d[x] == d[i] + 1 && edges[x][i].cap > edges[x][i].flow)
{
ok = 1;
x = i; p[Count++] = i;
}
}
if(ok == 0)
{
min = size + 1;
for(i = 0; i < size + 2 ; i++)
{
if(edges[x][i].cap > edges[x][i].flow)
{
if(d[i] < min)
{
min = d[i];
m = i;
}
}
}
if(--num[d[x]] == 0)
break;
d[x] = min + 1; num[d[x]]++;
//p[Count++] = m;
//x = m;
if(x != s)
{
x = p[Count - 2];
Count --;
}
}
}
return flow;
}
int main()
{
int faSize, haoSize, linkSize, i, j;
int start, end, value;
char temp[100];
while(scanf("%d", &size) != EOF)
{
s = size; t = size + 1;
scanf("%d%d%d", &faSize, &haoSize, &linkSize);
for(i = 0; i < size + 2; i++)
{
visit[i] = 0; d[i] = 0;
for(j = 0; j < size + 2; j++)
{
edges[i][j].cap = 0; edges[i][j].flow = 0;
}
}
//cout << linkSize << endl;
while(linkSize--)
{
scanf("%s",temp);
sscanf(temp,"(%d,%d)%d",&start,&end,&value);
//scanf("(%d,%d)%d", &start, &end, &value);
//cout << start << " " << end << " " << value;
edges[start][end].cap = value;
}
while (faSize--)
{
scanf("%s",temp);
sscanf(temp, "(%d)%d", &end, &value);
edges[s][end].cap = value;
}
while (haoSize--)
{
scanf("%s",temp);
sscanf(temp, "(%d)%d", &start, &value);
edges[start][t].cap = value;
}
cout << maxFlow() <<endl;
}
}