您的位置:首页 > 其它

最大流入门 之 poj 1273

2014-05-07 00:50 330 查看
//  [5/7/2014 Sjm]
/*
图论之最大流:
Ford-Fulkerson方法 dfs 实现
第一次接触网络流的题目,卡了好久。。。最后终于理解了代码,自己能敲出来了。。。
教训: (体会了算法的思想 != 能写出好的代码) => 要 知行合一

对代码细节理解(需要理解的关键位置):
1)对于 void Add_edge(int from, int to, int cap) 函数:
   在构建出 s->t  的正向边后,立即构建 t->s 的反向边(容量为0)
2)dfs 回朔时,正向边与反向边容量变化。
*/
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

const int MAX_M = 200, INF = 0x3f3f3f3f;
struct edge { int to, cap, rev; };
//     边   {终点, 容量, 反向边}
vector<edge> G[MAX_M];  // 邻接表构图
bool used[MAX_M];  // 用于 dfs 时判断点是否被访问过。

// 增加一条
void Add_edge(int from, int to, int cap) {
edge e1 = { to, cap, G[to].size() };
G[from].push_back(e1);
// 增加 from -> to 的正向边
edge e2 = { from, 0, G[from].size() - 1 };
// 增加 to -> from 的反向边
G[to].push_back(e2);
}

int Dfs(int v, int t, int f) {
if (v == t) return f;
used[v] = true;
for (int i = 0; i < G[v].size(); i++) {
edge &e = G[v][i];
if (!used[e.to] && e.cap > 0) {
int d = Dfs(e.to, t, min(f, e.cap));
if (d > 0) {
e.cap -= d;
// 增流后,正向边容量减少 d
G[e.to][e.rev].cap += d;
// 增流后,反向边容量增加 d
return d;
}
}
}
return 0;
}

int Max_flow(int s, int t) {
int max_flow = 0;
for (;;) {
memset(used, 0, sizeof(used));
int f = Dfs(s, t, INF);
if (!f) return max_flow;
max_flow += f;
}
}

int main()
{
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
int n, m;
while (~scanf("%d %d", &n, &m))
{
for (int i = 0; i < n; i++) {
int from, to, flow;
scanf("%d %d %d", &from, &to, &flow);
Add_edge(from - 1, to - 1, flow);
}
printf("%d\n", Max_flow(0, m - 1));
for (int i = 0; i < m; i++) {
G[i].clear();
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  最大流 入门 poj 1273