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吧。。?

原文地址:https://www.cnblogs.com/Drenight/p/8611316.html