zoukankan      html  css  js  c++  java
  • Dinic模板

    #include<bits/stdc++.h>
    
    using namespace std;
    #define ll long long
    const int maxn=3e5;
    const int INF=0x3f3f3f3f;
    
    struct Edge{
        int u,v,cap,flow;
    };
    
    int n,m,s,t;
    vector<Edge>edges;
    vector<int>G[maxn];
    int vis[maxn];
    int d[maxn];
    int cur[maxn];
    
    void init(){
        edges.clear();
        for(int i=0;i<maxn;i++)G[i].clear();
    }
    
    int BFS(){
        memset(vis,0,sizeof vis);
        queue<int>Q;
        Q.push(s);
        d[s]=0;
        vis[s]=1;
        while(!Q.empty()){
            int x=Q.front();Q.pop();
            for(int i=0;i<G[x].size();i++){
                Edge &e=edges[G[x][i]];
                if(!vis[e.v] && e.cap>e.flow){
                    vis[e.v]=1;
                    d[e.v]=d[x]+1;
                    Q.push(e.v);
                }
            }
        }
        return vis[t];
    }
    void addedge(int u,int v,int cap){
        edges.push_back((Edge){u,v,cap,0});
        edges.push_back((Edge){v,u,0,0});
        m=edges.size();
        G[u].push_back(m-2);
        G[v].push_back(m-1);
    }
    int DFS(int x,int a){
        if(x==t||a==0)return a;
        int flow=0,f;
        for(int& i=cur[x];i<G[x].size();i++){
            Edge& e=edges[G[x][i]];
            if(d[x]+1==d[e.v] && (f=DFS(e.v,min(a,e.cap-e.flow)))>0){
                e.flow+=f;
                edges[G[x][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if(a==0)break;
            }
        }
        return flow;
    };
    
    int maxflow(int _s,int _t){
        s=_s;t=_t;
        int flow=0;
        while(BFS()){
            memset(cur,0,sizeof cur);
            flow+=DFS(_s,INF);
        }
        return flow;
    }
    

    BFS对残量网络进行层次图距离测算,DFS贪婪扩充

    DFS(x,a)表示当前位于x节点,有a的最大流到达x

    当a为0的时候意味着已经访问过的x的后继点已经可以把a全部输送到终点,那么x的其他后继点就不用再从x访问了

    当前弧优化就记录了x点之前被访问过的后继点

    //#include<bits/stdc++.h>
    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<string>
    #include<vector>
    #include<queue>
    #include<iostream>
    //#pragma comment(linker, "/STACK:1024000000,1024000000")  
    
    using namespace std;
    #define ll long long
    const int maxn=2e5;
    const int INF=0x3f3f3f3f;
    
    int d[maxn], cur[maxn], start, tend;  
    struct node  
    {  
        int to, cap, next;   
    }edge[maxn << 1];  
     
    int head[maxn];  
    bool vis[maxn];  
    int cnt;  
    void init(){
        memset(head,-1,sizeof head);
        cnt=0;
    }
    void addedge(int start, int to, int cap)  
    {  
        edge[cnt].to = to;  
        edge[cnt].cap = cap;  
        edge[cnt].next = head[start];  
        head[start] = cnt++;  
    }  
    bool BFS()  
    {  
        memset(d, -1, sizeof(d));  
        int Q[maxn * 2];  
        int Thead, Ttail;  
        Thead = Ttail = 0;  
        Q[Ttail++] = start;;  
        d[start] = 0;  
    
        while (Thead<Ttail)  
        {  
            int x = Q[Thead];  
            if (x == tend)return true;  
            for (int i = head[x]; i != -1; i = edge[i].next)  
            {  
                int temp = edge[i].to;  
                if (d[temp] == -1 && edge[i].cap>0)//没有标记,且可行流大于0  
                {  
                    d[temp] = d[x] + 1;  
                    Q[Ttail++] = temp;  
                }  
            }  
            Thead++;  
        }  
        return false;//汇点是否成功标号,也就是说是否找到增广路  
    }  
    int DFS(int x, int cap)  
    {  
        if (x == tend)return cap;  
        int flow = 0, f;  
        for (int i = head[x]; i != -1; i = edge[i].next)  
        {  
            int temp = edge[i].to;  
            if (d[temp] == d[x] + 1 && edge[i].cap)  
            {  
                f = DFS(temp, min(cap - flow, edge[i].cap));  
                edge[i].cap -= f;  
                edge[i ^ 1].cap += f;  
                flow += f;  
                if (flow == cap)break;  
            }  
        }  
        if (!flow)d[x] = -2;//防止重搜  
        return flow;  
    }  
    int maxflow()  
    {  
        int flow = 0, f;  
        while (BFS())  
        {  
            while ((f = DFS(start, INF))>0)  
                flow += f;  
        }  
        return flow;  
    }  
    
    

    原模板似乎有些低效,补一个高效一些的

    链式前向星+数组模拟队列

    以后应该会用isap吧。。?

  • 相关阅读:
    Ionic app 通知在Moto 360 Watch上显示通知(2)
    Ionic app 通知在Moto 360 Watch上显示通知(1)
    Ionic App ActionSheet布局问题
    Ionic 图片延时加载
    Ionic app 上传图片之webApi接口
    Ionic app升级插件开发
    Ionic 添加java原生代码 报support.v4不存在问题
    Ionic 中badge的应用
    Java 期末复习提纲
    win10 + VS2015 + EF6 + MySQL
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611316.html
Copyright © 2011-2022 走看看