striver-模板-dinic

从 Trac 迁移的文章

这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。

原文章内容如下:

#include <stdio.h>
int b[100000], link[100000], last[100000];
int e[100000], w[100000], tt[100000], next[100000], g[100000], now[100000], f[100000], ff[100000];
int flow, top = 1, n, m, st, sw;
int ans;
void connect(int j, int k, int l)
{
   top ++;  e[top] = k;  w[top] = l;
   tt[top]  =  j;
   next[top]  =  link[j];
   link[j] = top;
   top ++;  e[top] = j; w[top] = 0;
   tt[top] = k;
   next[top] = link[k];
   link[k] = top;
}
void readin()
{
   int j, k, l, i;
   scanf("%d%d", &n, &m);
   st = 1; sw = n;
   for (i = 1; i <= m; i++)
     {
       scanf("%d%d%d", &j, &k, &l);
       connect(j, k, l);
     }
}  
int bfs()
{
  int t, ww, q;
  for (t = 1; t <= sw; t ++) {
    f[t] = -1;
    now[t] = link[t];
    }
  t = 0; ww = 1;  b[ww] = st;
  f[st] = 1;
  while (t < ww) {
    t ++;  q = link[b[t]];
    while (q) {
      if (w[q] > 0 && f[e[q]] < 0) 
        {
          f[e[q]] = f[b[t]] + 1;
          if (e[q] == sw) return 1;
          ww ++; b[ww] = e[q];
        }
         q = next[q];
      }
   }
  return 0;
}
int min(int a, int b) { return (a > b ? b : a); }
void dinic()
{
   int i, q, t;
   i = st;     ff[st] = 10000000;
   while (f[st] != -1)   {
    q = now[i];
    while (q)  if (w[q] > 0 && f[e[q]] - 1 == f[i]) break;
               else q = next[q];
    if (q) {
     now[i] = q;  i = e[q]; g[e[q]] = q;
     ff[e[q]] = min(ff[tt[q]], w[q]);
     if (i == sw) {
         ans += ff[sw];
         while (i != st)
          {
           w[g[i]] -= ff[sw];
           w[g[i] ^ 1] += ff[sw];
           i = tt[g[i]];
          }
       }
   }
   else {
      f[i] = -1;
      i = tt[g[i]];
     }
   }
}
int main(){
  readin();
  ans = 0;
  while (bfs())  dinic();
  printf("%d\n", ans);
}

#include

int b[100000], link[100000], last[100000];

int e[100000], w[100000], tt[100000], next[100000], g[100000], now[100000], f[100000], ff[100000];

int flow, top = 1, n, m, st, sw;

int ans;

void connect(int j, int k, int l)

{

top ++; e[top] = k; w[top] = l;

tt[top] = j;

next[top] = link[j];

link[j] = top;

top ++; e[top] = j; w[top] = 0;

tt[top] = k;

next[top] = link[k];

link[k] = top;

}

void readin()

{

int j, k, l, i;

scanf("%d%d", &n, &m);

st = 1; sw = n;

for (i = 1; i <= m; i++)

{

scanf("%d%d%d", &j, &k, &l);

connect(j, k, l);

}

}

int bfs()

{

int t, ww, q;

for (t = 1; t <= sw; t ++) {

f[t] = -1;

now[t] = link[t];

}

t = 0; ww = 1; b[ww] = st;

f[st] = 1;

while (t < ww) {

t ++; q = link[b[t]];

while (q) {

if (w[q] > 0 && f[e[q]] < 0)

{

f[e[q]] = f[b[t]] + 1;

if (e[q] == sw) return 1;

ww ++; b[ww] = e[q];

}

q = next[q];

}

}

return 0;

}

int min(int a, int b) { return (a > b ? b : a); }

void dinic()

{

int i, q, t;

i = st; ff[st] = 10000000;

while (f[st] != -1) {

q = now[i];

while (q) if (w[q] > 0 && f[e[q]] - 1 == f[i]) break;

else q = next[q];

if (q) {

now[i] = q; i = e[q]; g[e[q]] = q;

ff[e[q]] = min(ff[tt[q]], w[q]);

if (i == sw) {

ans += ff[sw];

while (i != st)

{

w[g[i]] -= ff[sw];

w[g[i] ^ 1] += ff[sw];

i = tt[g[i]];

}

}

}

else {

f[i] = -1;

i = tt[g[i]];

}

}

}

int main(){

readin();

ans = 0;

while (bfs()) dinic();

printf("%d\n", ans);

}