zoukankan      html  css  js  c++  java
  • 最大流EK算法模板

      最近学了下最大流算法,大概思想算是懵懵懂懂了,现在想把模板记录下来,以备后面深刻学习之用。

      

     1 #include<cstdio>
     2 #include<cstring>
     3 using namespace std;
     4 
     5 #define _clr(x, y) memset(x, y, sizeof (x))
     6 #define Min(x, y) (x < y ? x : y)
     7 #define INF 0x3f3f3f3f
     8 #define N 210
     9 
    10 int map[N][N];
    11 int pre[N], Sta[N];
    12 bool used[N];
    13 int n, m;
    14 
    15 //bfs判断s--t之间是否还存在增广路
    16 bool bfs(int s, int t)
    17 {
    18     _clr(used, 0);
    19     _clr(pre, -1);
    20     int top=1;
    21     Sta[top++] = s;
    22     used[s] = true;
    23     while(top)
    24     {
    25         int v = Sta[--top];
    26         for(int i=1; i<=n; i++)
    27         {
    28             if(map[v][i] && !used[i])
    29             {
    30                 used[i] = true;
    31                 pre[i] = v;
    32                 if(i==t)
    33                     return true;
    34                 Sta[top++] = i;
    35             }
    36         }
    37     }
    38     return false;
    39 }
    40 
    41 int EK(int s, int t)
    42 {
    43     //初始化最大流为0
    44     int maxFlow=0, d;
    45 
    46     //若s--t之间存在增广路
    47     while(bfs(s, t))
    48     {
    49         d = INF;
    50         //找到最小的可增量
    51         for(int i=t; i!=s; i=pre[i])
    52             d = Min(d, map[pre[i]][i]);
    53 
    54         //添加反向边,更新残留网络
    55         for(int i=t; i!=s; i=pre[i])
    56         {
    57             map[pre[i]][i] -= d;
    58             map[i][pre[i]] += d;
    59         }
    60         maxFlow += d;
    61     }
    62     return maxFlow;
    63 }
    64 
    65 
    66 int main()
    67 {
    68     int x, y, z;
    69     while(~scanf("%d%d", &m, &n))
    70     {
    71         _clr(map, 0);
    72         for(int i=0; i<m; i++)
    73         {
    74             scanf("%d%d%d",&x, &y, &z);
    75             map[x][y] += z;
    76         }
    77         printf("%d
    ",EK(1, n));
    78     }
    79     return 0;
    80 }

    Fulkersion_ford算法和Ekaf算法基本 是一样的,不同之处在与u搜索增广路时,一个用队列保存,一个用栈保存;

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <queue>
     4 #define _clr(x, y) memset(x, y, sizeof(x))
     5 #define Min(x, y) (x < y ? x : y)
     6 #define INF 0x3f3f3f3f
     7 #define N 110
     8 #define M 1005
     9 using namespace std;
    10 
    11 int edge[N][N], n;
    12 int pre[N], rec[N];
    13 int alpha[N], Sta[N];
    14 int S, T;
    15 
    16 void Ford_Fulkerson()
    17 {
    18     int maxf=0;
    19     while(1)
    20     {
    21         int top=0;
    22         _clr(pre, -1);
    23         _clr(alpha, 0);
    24         pre[S] = S;
    25         alpha[S] = INF;
    26         Sta[top++] = S;
    27         while(top)
    28         {
    29             int u = Sta[--top];
    30             for(int i=0; i<=T; i++)
    31             {
    32                 if(edge[u][i]>0 && pre[i]==-1)
    33                 {
    34                     pre[i] = u;
    35                     alpha[i] = Min(alpha[u], edge[u][i]);
    36                     Sta[top++] = i;
    37                 }
    38             }
    39             if(alpha[T]) break;
    40         }
    41         if(alpha[T]==0) break;
    42 
    43         maxf += alpha[T];
    44         for(int i=T; i!=S; i=pre[i])
    45         {
    46             edge[pre[i]][i] -= alpha[T];
    47             edge[i][pre[i]] += alpha[T];
    48         }
    49     }
    50     printf("%d
    ", maxf);
    51 }
    52 
    53 int main()
    54 {
    55     int m, num, k;
    56     while(~scanf("%d%d", &m, &n))
    57     {
    58         int pig[M], last[M];
    59         S=0, T=n+1;
    60         _clr(edge, 0);
    61         _clr(last, 0);
    62         for(int i=1; i<=m; i++) scanf("%d", pig+i);
    63         for(int i=1; i<=n; i++)
    64         {
    65             scanf("%d", &num);
    66             while(num--)
    67             {
    68                 scanf("%d", &k);
    69                 if(last[k]==0)
    70                     edge[S][i] += pig[k];
    71                 else
    72                     edge[last[k]][i] = INF;
    73                 last[k] = i;
    74             }
    75             scanf("%d", &edge[i][T]);
    76         }
    77         Ford_Fulkerson();
    78     }
    79     return 0;
    80 }
    View Code
  • 相关阅读:
    VB获取对象成员
    VB一键扫雷
    VBS代码
    C# LINQ GroupBy
    C# 元组和值元组
    数据结构笔记
    DoTween使用
    Unity中常用的数据结构总结
    Unity 坐标系转换
    .Net中C# Dictionary 用法
  • 原文地址:https://www.cnblogs.com/khan724/p/4141787.html
Copyright © 2011-2022 走看看