zoukankan      html  css  js  c++  java
  • 【网络流】——搞搞dinic

    只是搞一搞而已。

    https://www.luogu.org/problem/P3376网络流最大流板子。

    程序部分参考自大大的题解。

    Dinic:

    1.从s跑一遍bfs来分层,如果能分到t层,请转至2。

    2.跑dfs,求出当前的flow,加到答案中,欲知细节请到3。

    3.dfs(u,t,lim)表示(当前点,汇点,路上最小弧),首先预判一下两种情况:(1.到汇点了,即u==t 2.最小弧为0,即lim==0,都可以直接return lim)

      然后跑dfs:往哪个方向走?(往分层处,即新点深度是旧点+1,并且能走(f=dfs(v,t,min(lim,w)),即找增广路),这时候更新路径:原路-f,反向+f,flow+f,lim-f,判断一下lim如果小于等于0就不用再往下增广了。最后返回flow。

    4.最后返回flow的和就好了。

    5.可以选择弧优化,一点小细节,具体看程序:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<queue>
     5 using namespace std;
     6 const int inf=1e9;
     7 const int N=1e6+10;
     8 int n,m,S,T,cnt=-1,maxflow,head[N],cur[N],deep[N];
     9 queue<int> q;
    10 struct edge{
    11     int to,next,w;
    12 }e[N*2];
    13 void addedge(int from,int to,int w){
    14     e[++cnt]=(edge){to,head[from],w};
    15     head[from]=cnt;
    16 }
    17 int bfs(int s,int t){//将图分层。 
    18     for(int i=1;i<=n;i++) deep[i]=1e9+10;
    19     while(!q.empty()) q.pop();
    20     for(int i=1;i<=n;i++) cur[i]=head[i];
    21     deep[s]=0;
    22     q.push(s);
    23     while(!q.empty()){
    24         int u=q.front();
    25         q.pop();
    26         for(int i=head[u];i!=-1;i=e[i].next){
    27             int v=e[i].to;
    28             if(deep[v]>inf&&e[i].w){
    29                 deep[v]=deep[u]+1;
    30                 q.push(v);
    31             }
    32         }
    33     }
    34     if(deep[t]<inf) return true;
    35     else return false;
    36 }
    37 int dfs(int u,int t,int lim){//lim=minedge(s->u) 
    38     if(!lim||u==t) return lim;//如果到了汇点或者边权为0则返回边权。
    39     int flow=0,f;
    40     for(int i=cur[u];i!=-1;i=e[i].next){
    41         cur[u]=i;//弧优化
    42         int v=e[i].to;
    43         if(deep[v]==deep[u]+1&&(f=dfs(v,t,min(lim,e[i].w)))){//如果这段能到达汇点并且服从分层 
    44             flow+=f;
    45             lim-=f;
    46             e[i].w-=f;
    47             e[i^1].w+=f;
    48             if(!lim) break;
    49         }
    50     }
    51     return flow;
    52 }//important
    53 void dinic(int s,int t){
    54     while(bfs(s,t)){
    55         maxflow+=dfs(s,t,inf);
    56     }
    57 }
    58 int main(){
    59     scanf("%d%d%d%d",&n,&m,&S,&T);
    60     int x,y,z;
    61     memset(head,-1,sizeof(head));
    62     for(int i=1;i<=m;i++){
    63         scanf("%d%d%d",&x,&y,&z);
    64         addedge(x,y,z);
    65         addedge(y,x,0);
    66     }
    67     dinic(S,T);
    68     printf("%d",maxflow);
    69     return 0;
    70 }

    本来想搞ISAP,但是懒,鸽着吧。

    ——抓住了时间,却不会利用的人,终究也逃不过失败的命运。
  • 相关阅读:
    Stanford NLP 课程笔记之计算字符串距离
    Stanford NLP 课堂笔记之正则表达式
    最长回文子串
    java面向对象
    java中数组的定义
    AtCoder Beginner Contest 100 C(思维)
    Codeforces 1000B Light It Up(思维)
    jq的链式调用.end();
    解决css中display:inline-block的兼容问题
    解决css中display:inline-block产生的空隙问题
  • 原文地址:https://www.cnblogs.com/Nelson992770019/p/11285448.html
Copyright © 2011-2022 走看看