zoukankan      html  css  js  c++  java
  • 网络流算法

    dinic 算法

    时间复杂度 O(n*n*e) 

      1 struct node{
      2     int u,v,next,c;
      3 }edge[maxn<<1];
      4 int head[maxn];
      5 int cnt,dis[maxn],n,m,ans;
      6 
      7 void init(){
      8     memset(head,-1,sizeof(head));
      9     cnt=0;
     10     memset(dis,-1,sizeof(dis));
     11     ans=0;
     12 }
     13 void add(int a,int b,int c){
     14     edge[cnt].u=a;
     15     edge[cnt].v=b;
     16     edge[cnt].c=c;
     17     edge[cnt].next=head[a];
     18     head[a]=cnt++;
     19 }
     20 bool bfs(){
     21     memset(dis,-1,sizeof(dis));
     22     queue<int>q;
     23     dis[1]=0;
     24     q.push(1);
     25     int i,cur;
     26     while(!q.empty()) {
     27         cur=q.front();
     28         q.pop();
     29         for (int i=head[cur];i!=-1;i=edge[i].next){
     30             if(dis[edge[i].v]==-1&&edge[i].c>0){
     31                 dis[edge[i].v]=dis[cur]+1;
     32                 q.push(edge[i].v);
     33             }
     34         }
     35     }
     36     if(dis[m]<0) return 0;
     37     return 1;
     38 }
     39 int fnd(int x,int low){
     40     int a;
     41     if(x==m) return low;
     42     for (int i=head[x];i!=-1;i=edge[i].next){
     43         int v=edge[i].v;
     44         if(dis[v]==dis[x]+1&&edge[i].c>0&&(a=fnd(v,min(low,edge[i].c)))){
     45             edge[i].c-=a;
     46             edge[i^1].c+=a;
     47             return a;
     48         }
     49     }
     50     return 0;
     51 }
     52 void Dinic(){
     53     int temp;
     54     while(bfs()){
     55         temp=fnd(1,inf);
     56         ans+=temp;
     57     }
     58     printf("%d
    ",ans);
     59 }
     60 
     61 各种优化:
     62 
     63 #include <iostream>  
     64 #include <cstdio>  
     65 #include <cstring>  
     66 #include <queue>  
     67 #define inf 0x3f3f3f3f3f3f3f3f  
     68 #define ll long long  
     69 #define MAXN 10005  
     70 using namespace std;  
     71 int n,m;//点数、边数   
     72 int sp,tp;//原点、汇点   
     73 struct node  
     74 {  
     75     int v,next;  
     76     ll cap;  
     77 }mp[MAXN*10];  
     78 int pre[MAXN],dis[MAXN],cur[MAXN];//cur为当前弧优化,dis存储分层图中每个点的层数(即到原点的最短距离),pre建邻接表  
     79 int cnt=0;  
     80 void init()//不要忘记初始化  
     81 {  
     82     cnt=0;  
     83     memset(pre,-1,sizeof(pre));  
     84 }  
     85 void add(int u,int v,int w)//加边   
     86 {  
     87     mp[cnt].v=v;  
     88     mp[cnt].cap=w;  
     89     mp[cnt].next=pre[u];  
     90     pre[u]=cnt++;  
     91 }  
     92 bool bfs()//建分层图  
     93 {  
     94     memset(dis,-1,sizeof(dis));  
     95     queue<int>q;  
     96     while(!q.empty())  
     97     q.pop();  
     98     q.push(sp);  
     99     dis[sp]=0;  
    100     int u,v;  
    101     while(!q.empty())  
    102     {  
    103         u=q.front();  
    104         q.pop();  
    105         for(int i=pre[u];i!=-1;i=mp[i].next)  
    106         {  
    107             v=mp[i].v;  
    108             if(dis[v]==-1&&mp[i].cap>0)  
    109             {  
    110                 dis[v]=dis[u]+1;  
    111                 q.push(v);  
    112                 if(v==tp)  
    113                 break;  
    114             }  
    115         }  
    116     }  
    117     return dis[tp]!=-1;  
    118 }  
    119 ll dfs(int u,ll cap)//寻找增广路  
    120 {  
    121     if(u==tp||cap==0)  
    122     return cap;  
    123     ll res=0,f;  
    124     for(int &i=cur[u];i!=-1;i=mp[i].next)  
    125     {  
    126         int v=mp[i].v;  
    127         if(dis[v]==dis[u]+1&&(f=dfs(v,min(cap-res,mp[i].cap)))>0)  
    128         {  
    129             mp[i].cap-=f;  
    130             mp[i^1].cap+=f;  
    131             res+=f;  
    132             if(res==cap)  
    133             return cap;  
    134         }  
    135     }  
    136     if(!res)  
    137     dis[u]=-1;  
    138     return res;  
    139 }  
    140 ll dinic()  
    141 {  
    142     ll ans=0;  
    143     while(bfs())  
    144     {  
    145         for(int i=1;i<=n;i++)  
    146         cur[i]=pre[i];  
    147         ans+=dfs(sp,inf);  
    148     }  
    149     return ans;  
    150 }  
    151 int main()  
    152 {  
    153       
    154 return 0;  
    155 }
    View Code

     当前弧优化:

    #include <cstdio>  
    #include <cstring>  
    #include <algorithm>  
    #include <functional>  
    #include <queue>  
    #include <vector>  
    using namespace std;  
    const int maxn=1e5+10,inf=0x7fffffff;  
    int n,m,f,e,s,t;  
    struct Edge{  
        int u,v,c,flow;  
        Edge(int a,int b,int cc,int f):u(a),v(b),c(cc),flow(f){}  
    };  
    struct Dinic{  
        int s,t;  
        vector<Edge>edges;  
        vector<int>pre[maxn];  
        bool vis[maxn];  
        int dis[maxn];  
        int cur[maxn];  
        void init(){  
            for (int i=0;i<=n+1;i++)  
                pre[i].clear();  
            edges.clear();  
        }  
        void AddEdge(int a,int b,int c){  
            edges.push_back(Edge(a,b,c,0));  
            edges.push_back(Edge(b,a,0,0));  
            int mm=edges.size();  
            pre[a].push_back(mm-2);  
            pre[b].push_back(mm-1);  
        }  
        bool bfs(){  
            memset(vis,false,sizeof(vis));  
            queue<int>q;  
            q.push(s);  
            vis[s]=1;  
            dis[s]=0;  
            while(!q.empty()){  
                int  x=q.front();q.pop();  
            for (int i=0;i<pre[x].size();i++){  
                Edge &e=edges[pre[x][i]];  
                if(!vis[e.v]&& e.c>e.flow){  
                    dis[e.v]=dis[x]+1;  
                    vis[e.v]=1;  
                    q.push(e.v);  
                }  
            }  
            }  
            return vis[t];  
        }  
        int dfs(int x,int cap){  
            if(x==t||cap==0) return cap;  
            int f,flow=0;  
            for (int &i=cur[x];i<pre[x].size();i++){  
                cur[x]=i;
                Edge &e=edges[pre[x][i]];  
                if(dis[e.v]==dis[x]+1 && (f=dfs(e.v,min(cap,e.c-e.flow)))){  
                    e.flow+=f;  
                    edges[pre[x][i]^1].flow-=f;  
                    flow+=f;  
                    cap-=f;  
                    if(cap==0) break;  
                }  
            }  
            return flow;  
        }  
        int Maxflow(int s,int t){  
            this->s=s;  
            this->t=t;  
            int flow=0;  
            while(bfs()) {  
                memset(cur,0,sizeof(cur));  
                flow+=dfs(s,inf);  
            }  
            return flow;  
        }  
    }dc;
    View Code

    EK算法模板 算法复杂度 n*m*m (n为点数,m为边数) 源点 1, 汇点 n。

    const int maxn=310,inf=0x7fffffff;
    int pre[maxn],mat[maxn][maxn];
    bool vis[maxn];
    int n,m;
    int Augment(){
        int v;
        bool fnd=false;
        memset(pre,0,sizeof(pre));
        memset(vis,false,sizeof(vis));
        pre[1]=0;
        vis[1]=1;
        deque<int>q;
        q.push_back(1);
        while(!q.empty()){                 
            v=q.front();
            q.pop_front(); 
            for (int i=1;i<=m;i++){
                if(mat[v][i]>0&&!vis[i]){        //找到能走且为未走过的边
                    vis[i]=1;
                    pre[i]=v;
                    if(i==m){
                        fnd=1;
                        q.clear();
                        break;
                    }
                    else q.push_back(i);
                }
            }
        }
        if(!fnd) return 0;
        v=m;
        int mi=inf;
        while(pre[v]){
            mi=min(mi,mat[pre[v]][v]);
            v=pre[v];
        }
        v=m;
        while(pre[v]){
            mat[pre[v]][v]-=mi;
            mat[v][pre[v]]+=mi;
            v=pre[v];
        }
        return mi;
    }
    View Code

    参考博客:

    https://blog.csdn.net/lxy767087094/article/details/53606891

    https://blog.csdn.net/hitwhacmer1/article/details/47019789

    http://acm.pku.edu.cn/summerschool/gw_netflow.pdf

    http://www.cnblogs.com/jianrenfang/p/7253715.html

  • 相关阅读:
    20171017/20171018
    BZOJ[3193] [JLOI2013]地形生成
    BZOJ[1009] [HNOI2008]GT考试
    BZOJ[4767] 两双手
    BZOJ[4013] [HNOI2015]实验比较
    BZOJ[1925] [Sdoi2010]地精部落
    20171015 杂题
    20171015
    20171014
    USACO 2015 December Contest, Gold Problem 3. Bessie's Dream
  • 原文地址:https://www.cnblogs.com/acerkoo/p/9490335.html
Copyright © 2011-2022 走看看