洛谷 P3376 【模板】网络最大流 题解

今天学了网络最大流,EK 和 Dinic 主要就是运用搜索求增广路,Dinic 相当于 EK 的优化,先用bfs求每个点的层数,再用dfs寻找并更新那条路径上的值。

EK 算法

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<queue>
  6 #define maxn 1000001
  7 #define INF 2147483647
  8 using namespace std;
  9 int cnt=1,head[maxn];
 10 int dis[maxn],vis[maxn],flow[maxn],last[maxn],maxflow;
 11 struct node
 12 {
 13     int u,v,w,nex;
 14 }edge[maxn];
 15 queue<int>q;
 16 int S,T,n,m;
 17 inline int read()
 18 {
 19     int x=0;
 20     bool f=1;
 21     char c=getchar();
 22     for(; !isdigit(c); c=getchar()) if(c=='-') f=0;
 23     for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0';
 24     if(f) return x;
 25     return 0-x;
 26 }
 27 inline void add(int x,int y,int z)
 28 {     
 29     cnt++;
 30     edge[cnt].u=x;
 31     edge[cnt].v=y;
 32     edge[cnt].w=z;
 33     edge[cnt].nex=head[x];
 34     head[x]=cnt;
 35 }
 36 inline bool bfs(int S,int T)
 37 {         
 38     for(int i=1;i<=n;i++)
 39     {
 40         last[i]=0;
 41         vis[i]=-1;
 42     }
 43     q.push(S);
 44     dis[S]=0;
 45     vis[S]=1;
 46     flow[S]=INF;
 47     while(!q.empty())
 48     {
 49         int u=q.front();
 50         q.pop();
 51         vis[u]=0;
 52         for(int i=head[u];i!=-1;i=edge[i].nex)
 53         {
 54             int v=edge[i].v;
 55             if(edge[i].w>0&&vis[v]==-1)
 56             {       
 57                 flow[v]=min(flow[u],edge[i].w);
 58                 last[v]=i;                
 59                 q.push(v);
 60                 vis[v]=0;
 61             }
 62         }
 63     }
 64     if(vis[T]!=-1)return true;          
 65     return false;
 66 }
 67 inline void update(int S,int T)
 68 {        
 69     int now=T;
 70     while(now!=S)
 71     {
 72         int i=last[now];
 73         edge[i].w-=flow[T];
 74         edge[i^1].w+=flow[T];
 75         now=edge[i].u;          
 76     }
 77     maxflow+=flow[T];          
 78 }
 79 inline void EK()
 80 {
 81 
 82     maxflow=0;
 83     while(bfs(S,T)==true)
 84     {
 85         update(S,T);
 86     }
 87 }
 88 int main()
 89 {
 90     memset(head,-1,sizeof(head));
 91     n=read();m=read();S=read();T=read();
 92     for(int i=1;i<=m;i++)
 93     {
 94         int x,y,z;
 95         x=read();y=read();z=read();
 96         add(x,y,z);add(y,x,0);
 97     }
 98     EK();
 99     printf("%d",maxflow);
100     return  0;
101 }

Dinic 算法

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<queue>
  6 #define maxn 1000001
  7 #define INF 2147483647
  8 using namespace std;
  9 int cnt=1,head[maxn],level[maxn];
 10 struct node
 11 {
 12     int u,v,w,nex;
 13 }edge[maxn];
 14 queue<int> q;
 15 int S,T,n,m;
 16 inline int read()
 17 {
 18     int x=0;
 19     bool f=1;
 20     char c=getchar();
 21     for(; !isdigit(c); c=getchar()) if(c=='-') f=0;
 22     for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0';
 23     if(f) return x;
 24     return 0-x;
 25 }
 26 inline void write(int x)
 27 {
 28     if(x<0){putchar('-');x=-x;}
 29     if(x>9)write(x/10);
 30     putchar(x%10+'0');
 31 }
 32 inline void add(int x,int y,int z)
 33 {     
 34     cnt++;
 35     edge[cnt].u=x;
 36     edge[cnt].v=y;
 37     edge[cnt].w=z;
 38     edge[cnt].nex=head[x];
 39     head[x]=cnt;
 40 }
 41 inline bool bfs()
 42 {
 43     memset(level,-1,sizeof(level));
 44     level[S]=0;
 45     q.push(S);
 46     while(!q.empty())
 47     {
 48         int from=q.front();
 49         q.pop();
 50         for(int i=head[from];i!=-1;i=edge[i].nex)
 51         {
 52             int to=edge[i].v;
 53             if(edge[i].w>0&&level[to]==-1)
 54             {
 55                 level[to]=level[from]+1;
 56                 q.push(to);
 57             }
 58         }
 59     }
 60     if(level[T]!=-1)return true;
 61     return false;
 62 }
 63 inline int dfs(int u,int flow)
 64 {
 65     if(u==T)return flow;
 66     int ret=flow;
 67     for(int i=head[u];i!=-1;i=edge[i].nex)
 68     {
 69         if(ret<=0)break;
 70         int to=edge[i].v;
 71         if(edge[i].w>0&&level[u]+1==level[to])
 72         {
 73             int k=dfs(to,min(edge[i].w,ret));
 74             ret-=k;
 75             edge[i].w-=k;
 76             edge[i^1].w+=k;
 77         }
 78     }
 79     return flow-ret;
 80 }
 81 inline int dinic()
 82 {
 83     int ans=0;
 84     while(bfs()==true)ans+=dfs(S,INF);
 85     return ans;
 86 }
 87 int main()
 88 {
 89     memset(head,-1,sizeof(head));
 90     n=read();m=read();S=read();T=read();
 91     for(int i=1;i<=m;i++)
 92     {
 93         int x,y,z;
 94         x=read();y=read();z=read();
 95         add(x,y,z);
 96         add(y,x,0);
 97     }
 98     int res=dinic();
 99     write(res);
100     return 0;
101 }
请各位大佬斧正(反正我不认识斧正是什么意思)
原文地址:https://www.cnblogs.com/handsome-zyc/p/11237666.html