2013-team5/network-flow
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
/*
dinic
O(n^2*m)
first initial S & T
By Kotomi
*/
#include <cstring>
#include <queue>
using namespace std;
const int maxN = 2010;
const int maxM = 1000000;
const int INF = 1 << 30;
struct graph
{
int v, next, op, c;
}edge[maxM];
int lv[maxN], vect[maxN];
int S, T, tot;
void add(int u, int v, int c)
{
edge[++tot].v = v;
edge[tot].c = c;
edge[tot].next = vect[u];
vect[u] = tot;
edge[tot].op = tot + 1;
edge[++tot].v = u;
edge[tot].c = 0;
edge[tot].next = vect[v];
vect[v] = tot;
edge[tot].op = tot - 1;
}
bool build()
{
memset(lv, 0, sizeof(lv));
queue<int> Q;
Q.push(S);
lv[S] = 1;
while (!Q.empty()){
int u = Q.front();
Q.pop();
for (int it = vect[u]; it; it = edge[it].next){
int v = edge[it].v;
int c = edge[it].c;
if (c > 0 && !lv[v]){
lv[v] = lv[u] + 1;
Q.push(v);
if (v == T) return true;
}
}
}
return false;
}
int dfs(int u, int flow)
{
if (u == T || !flow) return flow;
int tp, now = 0;
for (int it = vect[u]; it; it = edge[it].next){
int v = edge[it].v;
int c = edge[it].c;
int op = edge[it].op;
if (c > 0 && lv[u] + 1 == lv[v]){
tp = dfs(v, min(flow, c));
now = now + tp;
flow = flow - tp;
edge[it].c -= tp;
edge[op].c += tp;
}
}
if (!now) lv[u] = 0;
return now;
}
int dinic()
{
int ans = 0;
while (build()) ans += dfs(S, INF);
return ans;
}
int init(int s, int t)
{
S = s, T = t, tot = 0;
memset(vect, 0, sizeof(vect));
}
}}}
/*
dinic
O(n^2*m)
first initial S & T
By Kotomi
*/
#include <cstring>
#include <queue>
using namespace std;
const int maxN = 2010;
const int maxM = 1000000;
const int INF = 1 << 30;
struct graph
{
int v, next, op, c;
}edge[maxM];
int lv[maxN], vect[maxN];
int S, T, tot;
void add(int u, int v, int c)
{
edge[++tot].v = v;
edge[tot].c = c;
edge[tot].next = vect[u];
vect[u] = tot;
edge[tot].op = tot + 1;
edge[++tot].v = u;
edge[tot].c = 0;
edge[tot].next = vect[v];
vect[v] = tot;
edge[tot].op = tot - 1;
}
bool build()
{
memset(lv, 0, sizeof(lv));
queue<int> Q;
Q.push(S);
lv[S] = 1;
while (!Q.empty()){
int u = Q.front();
Q.pop();
for (int it = vect[u]; it; it = edge[it].next){
int v = edge[it].v;
int c = edge[it].c;
if (c > 0 && !lv[v]){
lv[v] = lv[u] + 1;
Q.push(v);
if (v == T) return true;
}
}
}
return false;
}
int dfs(int u, int flow)
{
if (u == T || !flow) return flow;
int tp, now = 0;
for (int it = vect[u]; it; it = edge[it].next){
int v = edge[it].v;
int c = edge[it].c;
int op = edge[it].op;
if (c > 0 && lv[u] + 1 == lv[v]){
tp = dfs(v, min(flow, c));
now = now + tp;
flow = flow - tp;
edge[it].c -= tp;
edge[op].c += tp;
}
}
if (!now) lv[u] = 0;
return now;
}
int dinic()
{
int ans = 0;
while (build()) ans += dfs(S, INF);
return ans;
}
int init(int s, int t)
{
S = s, T = t, tot = 0;
memset(vect, 0, sizeof(vect));
}