这是初学网络流的时候从《算法竞赛进阶指南》抄下来的一份代码,自己理解的也不是很透彻。
注意,边要从 \(1\) 开始计,不然直接 \(xor\) 运算的话取反边会直接炸掉。
#include
#define int long long
namespace Basic {
template
Temp fh = 1; res = 0; char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') fh = -1;
for(; isdigit(ch); ch = getchar()) res = (res << 3) + (res << 1) + (ch ^ '0');
res = res * fh;
}
template
template
}
using namespace std;
using namespace Basic;
const int Maxn = 2e2 + 5;
const int Maxm = 5e3 + 5;
const int INF = 0x7fffffff >> 1;
struct e {
int to, nxt, flow;
} b[Maxm << 1];
int head[Maxn], ecnt = 1;
inline void add(int u, int v, int f) {b[++ecnt] = (e){v, head[u], f}; head[u] = ecnt;}
int depth[Maxn], curr[Maxn];
int n, m, st, ed;
int Max_flow, last_flow;
queue
inline bool bfs() {
memset(depth, 0, sizeof(depth));
while(!q.empty()) q.pop();
depth[st] = 1; q.push(st); curr[st] = head[st];
while(!q.empty()) {
int tnow = q.front(); q.pop();
for(register int i = head[tnow]; i; i = b[i].nxt) {
int tto = b[i].to, tw = b[i].flow;
if((!tw) || (depth[tto])) continue;
q.push(tto);
depth[tto] = depth[tnow] + 1; curr[tto] = head[tto];
if(tto == ed) return true;
}
}
return false;
}
int dfs(int t, int Flow) {
if(t == ed) return Flow;
int rest = Flow, k, i;
for(i = curr[t]; i && rest; i = b[i].nxt) {
int tto = b[i].to, tw = b[i].flow; curr[t] = i;
if((tw == 0) || (depth[tto] != depth[t] + 1)) continue;
k = dfs(tto, min(rest, tw));
rest -= k;
b[i].flow -= k;
b[i ^ 1].flow += k;
if(!k) depth[tto] == 0;
}
return Flow - rest;
}
signed main() {
read(n); read(m); read(st); read(ed);
int x, y, z;
while(m--) {
read(x); read(y); read(z);
add(x, y, z);
add(y, x, 0);
}
while(bfs()) {
/*
for(register int i = 1; i <= n; ++i) {
printf("%d ", depth[i]);
}
puts("");
*/
while(last_flow = dfs(st, INF)) Max_flow += last_flow;
}
printf("%d", Max_flow);
return 0;
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章