• 洛谷 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 }
    请各位大佬斧正(反正我不认识斧正是什么意思)
  • 相关阅读:
    PAT 顶级 1010 Lehmer Code (35 分)
    PAT 顶级 1010 Lehmer Code (35 分)
    CCF CSP 201909-4 推荐系统
    CCF CSP 201909-4 推荐系统
    Codeforces 1251C Minimize The Integer
    Codeforces 1251C Minimize The Integer
    CCF CSP 201803-4 棋局评估
    CCF CSP 201803-4 棋局评估
    【DP_树形DP专题】题单总结
    【DP_树形DP专题】题单总结
  • 原文地址:https://www.cnblogs.com/handsome-zyc/p/11237666.html
Copyright © 2020-2023  润新知