zoukankan      html  css  js  c++  java
  • 最大流dinic模板

    循环版,点的编号从0开始:

     1 const int MAXN = 2010;
     2 const int MAXM = 1200012;
     3 const int INF = 0x3f3f3f3f;
     4 struct Edge 
     5 {
     6     int to, next, cap, flow;
     7 }edge[MAXM];
     8 int tol;
     9 int head[MAXN];
    10 void init() 
    11 {
    12     tol = 2;
    13     memset(head, -1, sizeof(head));
    14 }
    15 void addedge(int u, int v, int w, int rw=0) 
    16 {
    17     edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = 0;
    18     edge[tol].next = head[u]; head[u] = tol++;
    19     edge[tol].to = u; edge[tol].cap = rw; edge[tol].flow = 0;    //存反向边
    20     edge[tol].next = head[v]; head[v] = tol++;
    21 }
    22 int Q[MAXN];
    23 int dep[MAXN], cur[MAXN], sta[MAXN];
    24 bool bfs(int s, int t, int n) 
    25 {
    26     int front = 0, tail = 0;
    27     memset(dep, -1, sizeof(dep[0])*(n+1));
    28     dep[s] = 0;
    29     Q[tail++] = s;
    30     while(front < tail)
    31     {
    32         int u = Q[front++];
    33         for(int i = head[u]; i != -1; i = edge[i].next) 
    34         {
    35             int v = edge[i].to;
    36             if(edge[i].cap > edge[i].flow && dep[v] == -1)                 
             {
    37 dep[v] = dep[u] + 1; 38 if(v == t) return true; 39 Q[tail++] = v; 40 } 41 } 42 } 43 return false; 44 } 45 int dinic(int s, int t, int n) { //s是源点编号,t是汇点编号,n是点的总数,返回最大流 46 int maxflow = 0; 47 while(bfs(s, t, n)) { 48 for(int i = 0; i < n; i++) cur[i] = head[i]; 49 int u = s, tail = 0; 50 while(cur[s] != -1) 51 { 52 if(u == t) 53 { 54 int tp = INF; 55 for(int i = tail-1; i >= 0; i--) 56 tp = min(tp, edge[sta[i]].cap-edge[sta[i]].flow); 57 maxflow+=tp; 58 for(int i = tail-1; i >= 0; i--) { 59 edge[sta[i]].flow+=tp; 60 edge[sta[i]^1].flow-=tp; 61 if(edge[sta[i]].cap-edge[sta[i]].flow==0) 62 tail = i; 63 } 64 u = edge[sta[tail]^1].to; 65 } 66 else 67 if(cur[u] != -1 && edge[cur[u]].cap > edge[cur[u]].flow && dep[u] + 1 == dep[edge[cur[u]].to]) 68 { 69 sta[tail++] = cur[u]; 70 u = edge[cur[u]].to; 71 } 72 else 73 { 74 while(u != s && cur[u] == -1) 75 u = edge[sta[--tail]^1].to; 76 cur[u] = edge[cur[u]].next; 77 } 78 } 79 } 80 return maxflow; 81 }

    dfs增广路版,点的编号从0开始:

     1 const int MAXN = 2010;
     2 const int MAXM = 1200012;
     3 const int INF = 0x3f3f3f3f;
     4 struct Edge 
     5 {
     6     int to, next, cap, flow;
     7 }edge[MAXM];
     8 int tol;
     9 int head[MAXN];
    10 void init() 
    11 {
    12     tol = 2;
    13     memset(head, -1, sizeof(head));
    14 }
    15 void addedge(int u, int v, int w, int rw=0) 
    16 {
    17     edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = 0;
    18     edge[tol].next = head[u]; head[u] = tol++;
    19     edge[tol].to = u; edge[tol].cap = rw; edge[tol].flow = 0;      //存反向边
    20     edge[tol].next = head[v]; head[v] = tol++;
    21 }
    22 int Q[MAXN];
    23 int dep[MAXN], cur[MAXN], sta[MAXN];
    24 bool bfs(int s, int t, int n) 
    25 {
    26     int front = 0, tail = 0;
    27     memset(dep, -1, sizeof(dep[0])*(n+1));
    28     dep[s] = 0;
    29     Q[tail++] = s;
    30     while(front < tail)
    31     {
    32         int u = Q[front++];
    33         for(int i = head[u]; i != -1; i = edge[i].next) 
    34         {
    35             int v = edge[i].to;
    36             if(edge[i].cap > edge[i].flow && dep[v] == -1)                 
    37                         {
    38                 dep[v] = dep[u] + 1;
    39                 if(v == t) return true;
    40                 Q[tail++] = v;
    41             }
    42         }
    43     }
    44     return false;
    45 }
    46 
    47 int dfs(int u,int t,int f)                             //dfs寻找增广路
    48 {
    49     if(u==t) return f;
    50     for(int i=head[u];i!=-1;i=edge[i].next)
    51     {
    52         int v=edge[i].to;
    53         if(edge[i].cap > edge[i].flow && dep[v]==dep[u]+1)
    54         {
    55             int d=dfs(v,t,min(f,edge[i].cap-edge[i].flow));
    56             if(d>0)
    57             {
    58                 edge[i].flow+=d;
    59                 edge[i^1].flow-=d;
    60                 return d;
    61             }
    62         }
    63     }
    64     return 0;
    65 }
    66 
    67 int dinic(int s, int t, int n) {      //s是源点编号,t是汇点编号,n是点的总数,返回最大流
    68     int maxflow = 0 , f;
    69     while(bfs(s, t, n))
    70     {
    71         while(f=dfs(s,t,INF))
    72             maxflow+=f;
    73     }
    74     return maxflow;
    75 }                

    不建反向边(一般用不到),点的编号从0开始:

     1 const int MAXN = 100010;
     2 const int MAXM = 1200012;
     3 const int INF = 0x3f3f3f3f;
     4 struct Edge 
     5 {
     6     int from,to, next, cap, flow;
     7 }edge[MAXM];
     8 int tol;
     9 int head[MAXN];
    10 void init() 
    11 {
    12     tol = 2;
    13     memset(head, -1, sizeof(head));
    14 }
    15 int min(int a,int b)
    16 {
    17 return a>b?b:a;
    18 }
    19 void addedge(int u, int v, int w, int rw=0) 
    20 {
    21     edge[tol].from=u;                            //记录起点
    22     edge[tol].to = v; edge[tol].cap = w; edge[tol].flow = 0;
    23     edge[tol].next = head[u]; head[u] = tol++;
    24 }
    25 int Q[MAXN];
    26 int dep[MAXN], cur[MAXN], sta[MAXN];
    27 bool bfs(int s, int t, int n) 
    28 {
    29     int front = 0, tail = 0;
    30     memset(dep, -1, sizeof(dep[0])*(n+1));
    31     dep[s] = 0;
    32     Q[tail++] = s;
    33     while(front < tail)
    34     {
    35         int u = Q[front++];
    36         for(int i = head[u]; i != -1; i = edge[i].next) 
    37         {
    38             int v = edge[i].to;
    39             if(edge[i].cap > edge[i].flow && dep[v] == -1)                 
    40                         {
    41                 dep[v] = dep[u] + 1;
    42                 if(v == t) return true;
    43                 Q[tail++] = v;
    44             }
    45         }
    46     }
    47     return false;
    48 }
    49 int dinic(int s, int t, int n) {       //s是源点编号,t是汇点编号,n是点的总数,返回最大流
    50     int maxflow = 0;
    51     while(bfs(s, t, n)) {
    52         for(int i = 0; i < n; i++) cur[i] = head[i];
    53         int u = s, tail = 0;
    54         while(cur[s] != -1)
    55         {
    56             if(u == t) 
    57             {
    58                 int tp = INF;
    59                 for(int i = tail-1; i >= 0; i--)
    60                     tp = min(tp, edge[sta[i]].cap-edge[sta[i]].flow);
    61                 maxflow+=tp;
    62                 for(int i = tail-1; i >= 0; i--) {
    63                     edge[sta[i]].flow+=tp;
    64                     edge[sta[i]^1].flow-=tp;
    65                     if(edge[sta[i]].cap-edge[sta[i]].flow==0)
    66                         tail = i;
    67                 }
    68                 u = edge[sta[tail]].from;
    69             }
    70             else 
    71                 if(cur[u] != -1 && edge[cur[u]].cap > edge[cur[u]].flow && dep[u] + 1 == dep[edge[cur[u]].to]) 
    72                 {
    73                     sta[tail++] = cur[u];
    74                     u = edge[cur[u]].to;
    75                 }
    76                 else 
    77                 {
    78                     while(u != s && cur[u] == -1)
    79                         u = edge[sta[--tail]].from;
    80                     cur[u] = edge[cur[u]].next;
    81                 }
    82         }
    83     }
    84     return maxflow;
    85 }         
  • 相关阅读:
    31
    30
    29
    28
    27
    26
    25
    23
    cesium 基础
    操作SDO_GEOMETRY字段
  • 原文地址:https://www.cnblogs.com/yaoyueduzhen/p/5020361.html
Copyright © 2011-2022 走看看