• 网络最大流dinic算法优化


    前置知识

    不会最大流板子的出门右转:https://www.cnblogs.com/yinyuqin/p/14508965.html

    小优化

    Dinic除了当前弧优化外,还有一点小优化(来自nealchen):在进行bfs分层时,从t点开始搜索分层,搜到s就直接停止搜索。

    因为剩下的未分层的点的层数一定大于等于s点,dfs时不会搜索到,所以可以大胆省去。

    于是就有了一点点优化:

    原来的:

    现在的:

    能看出来?

    注意原来分层中条件e[i].cap>0变成了e[i^1].cap>0。

    代码

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<algorithm>
     6 #include<stack>
     7 #include<set>
     8 #include<queue>
     9 const int maxn=205;
    10 int n,m,s,t,cnt=1,dis[maxn],cur[maxn],p[maxn];
    11 long long ans;
    12 using namespace std;
    13 struct node{
    14     int v,next;
    15     long long cap;
    16 }e[10005];
    17 void insert(int u,int v,int w){
    18     cnt++;
    19     e[cnt].v=v;
    20     e[cnt].next=p[u];
    21     e[cnt].cap=w;
    22     p[u]=cnt;
    23 }
    24 bool bfs(){
    25     memset(dis,0,sizeof(dis));
    26     dis[t]=1;
    27     queue<int> q;
    28     q.push(t);
    29     while(!q.empty()){
    30         int u=q.front();
    31         q.pop();
    32         for(int i=p[u];i!=-1;i=e[i].next){
    33             if(e[i^1].cap<=0) continue;
    34             int v=e[i].v;
    35             if(!dis[v]){
    36                 dis[v]=dis[u]+1;
    37                 q.push(v);
    38                 if(v==s) return 1;
    39             }
    40         }
    41     }
    42     return 0;
    43 }
    44 long long dfs(int u,long long maxflow){
    45     if(u==t||maxflow==0) return maxflow;
    46     long long f=0;
    47     for(int &i=cur[u];i!=-1;i=e[i].next){
    48         int v=e[i].v;
    49         if(dis[v]==dis[u]-1&&e[i].cap>0){
    50             long long flow=dfs(v,min(maxflow,e[i].cap));
    51             maxflow-=flow;
    52             e[i].cap-=flow;
    53             e[i^1].cap+=flow;
    54             f+=flow;
    55             if(maxflow==0) break;
    56         }
    57     }
    58     return f;
    59 }
    60 void dinic(){
    61     while(bfs()){
    62         for(int i=1;i<=n;i++) cur[i]=p[i];
    63         ans+=dfs(s,1e15);
    64     }
    65 }
    66 int main(){
    67     memset(p,-1,sizeof(p));
    68     scanf("%d%d%d%d",&n,&m,&s,&t);
    69     for(int i=1;i<=m;i++){
    70         int u,v,w;
    71         scanf("%d%d%d",&u,&v,&w);
    72         insert(u,v,w);
    73         insert(v,u,0);
    74     }
    75     dinic();
    76     cout<<ans;
    77     return 0;
    78 }
  • 相关阅读:
    抓老鼠
    我的寒假作业
    寒假作业
    大一上学期C语言学习总结
    我的三位老师
    自我介绍
    2019春季第七周作业
    第六周总结
    第五周作业及其总结
    2019春季第四周作业
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/14735962.html
Copyright © 2020-2023  润新知