POJ-1273(dinic-最大流,递归实现)

 

层次图

  层次图,就是把原图中的点按照到到源的距离分“层”,只保留不同层之间的边的图。

算法流程

  1、根据残量网络计算层次图(BFS)。
  2、在层次图中使用DFS进行增广直到不存在增广路。

  3、重复以上步骤直到无法增广。

const int INF = 0x7fffffff;
const int V = 205;
int cap[V ][V ];
int level[V ];
int n, m;
int S, D;
bool bfs()//对顶点进行标号,找出层次图
{
	queue<int> Q;
	while (!Q.empty()) Q.pop();
	memset(level, 0, sizeof(level));
	Q.push(S);
	level[S] = 1;
	int u, v;
	while (!Q.empty()) {
		u = Q.front();
		Q.pop();
		for (v = 1; v <= n; ++v) {
			if (!level[v] && cap[u][v] > 0) {
				level[v] = level[u] + 1;
				Q.push(v);
			}
		}
	}
	return level[D] != 0;//汇点是否在层次图中
}
int dfs(int u, int cp)//在层次图中寻找增广路径进行增广
{
	int tmp = cp;
	int v, t;
	if (u == D) return cp;
	for (v = 1; v <= n && tmp; ++v) {
		if (level[v] == level[u] + 1 && cap[u][v] > 0) {
			t = dfs(v, min(tmp, cap[u][v]));
			cap[u][v] -= t;
			cap[v][u] += t;
			tmp -= t;
		}
	}
	return cp - tmp;
}
int dinic()
{
	int ans, tmp_flow;
	ans = tmp_flow = 0;
	while (bfs()) {//汇点不在层次图中,算法终止
		while (tmp_flow = dfs(1, INF)) {
			ans += tmp_flow;
		}
	}
	return ans;
}
int main()
{
    int i, u, v, cost;
    while(scanf("%d%d", &m, &n) == 2) {//m is edge, n is vertex
		S = 1;
		D = n;
        memset(cap, 0, sizeof(cap));
        for(i = 0; i < m; i++) {
            cin >> u >> v >> cost;
            cap[u][v] += cost;
        }
        int f = dinic();
        printf("%d\n", f);
    }
    return 0;
}


 

你可能感兴趣的:(POJ-1273(dinic-最大流,递归实现))