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

来源:互联网 发布:数据分类汇总步骤 编辑:程序博客网 时间:2024/04/30 10:21
 

层次图

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

算法流程

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