网络流板子

最大流dinic板子

const int N = 1e6+10, S = N-2, T = N-1, INF = 0x3f3f3f3f;
int n;
struct edge {
    int to,w,next;
    edge(int to=0,int w=0,int next=0):to(to),w(w),next(next){}
} e[N];
int head[N], dep[N], vis[N], cur[N], cnt=1;
queue<int> Q;
int bfs() {
    REP(i,1,n) dep[i]=INF,vis[i]=0,cur[i]=head[i];
    dep[S]=INF,vis[S]=0,cur[S]=head[S];
    dep[T]=INF,vis[T]=0,cur[T]=head[T];
    dep[S]=0,Q.push(S);
    while (Q.size()) {
        int u = Q.front(); Q.pop();
        for (int i=head[u]; i; i=e[i].next) {
            if (dep[e[i].to]>dep[u]+1&&e[i].w) {
                dep[e[i].to]=dep[u]+1;
                Q.push(e[i].to);
            }
        }
    }
    return dep[T]!=INF;
}
int dfs(int x, int w) {
    if (x==T) return w;
    int used = 0;
    for (int i=cur[x]; i; i=e[i].next) {
        cur[x] = i;
        if (dep[e[i].to]==dep[x]+1&&e[i].w) {
            int f = dfs(e[i].to,min(w-used,e[i].w));
            if (f) used+=f,e[i].w-=f,e[i^1].w+=f;
            if (used==w) break;
        }
    }
    return used;
}
int dinic() {
    int ans = 0;
    while (bfs()) ans+=dfs(S,INF);
    return ans;
}
void add(int u, int v, int w) {
    e[++cnt] = edge(v,w,head[u]);
    head[u] = cnt;
    e[++cnt] = edge(u,0,head[v]);
    head[v] = cnt;
} 

费用流EK+spfa板子

const int N = 1e6+10, INF = 0x3f3f3f3f, S = N-2, T = N-1;
int n, m, flow, cost;
struct edge {
    int to,w,v,next;
    edge(int to=0,int w=0,int v=0,int next=0):to(to),w(w),v(v),next(next){}
} e[N];
int head[N], dep[N], vis[N], cur[N], f[N], cnt=1;
int pre[N],pre2[N];
queue<int> Q;
int spfa() {
    REP(i,1,n) f[i]=dep[i]=INF,vis[i]=0;
    f[S]=dep[S]=f[T]=dep[T]=INF;
    dep[S]=0,Q.push(S);
    while (Q.size()) {
        int u = Q.front(); Q.pop();
        vis[u] = 0;
        for (int i=head[u]; i; i=e[i].next) {
            if (dep[e[i].to]>dep[u]+e[i].v&&e[i].w) {
                dep[e[i].to]=dep[u]+e[i].v;
				pre[e[i].to]=u,pre2[e[i].to]=i;
                f[e[i].to]=min(f[u],e[i].w);
                if (!vis[e[i].to]) {
                    vis[e[i].to]=1;
                    Q.push(e[i].to);
                }
            }
        }
    }
    return dep[T]!=INF;
}
void EK(){
    while(spfa()) {
        int w = f[T];
        for (int u=T; u!=S; u=pre[u]) {
            e[pre2[u]].w-=w;
            e[pre2[u]^1].w+=w;
        }
        flow += w, cost += w*dep[T];
    }
}
void add(int u, int v, int w, int k) {
    e[++cnt] = edge(v,w,k,head[u]);
    head[u] = cnt;
    e[++cnt] = edge(u,0,-k,head[v]);
    head[v] = cnt;
}

 费用流dinic+dijkstra板子

#include <iostream>
#include <sstream>
#include <algorithm>
#include <cstdio>
#include <math.h>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <string.h>
#include <bitset>

#define REPP(i,a,b,d) for(int i=a; i<=b; i+=d)
#define REP(i,a,b) REPP(i,a,b,1)
#define REVV(i,a,b,d) for(int i=a; i>=b; i-=d)
#define REV(i,a,b) REVV(i,a,b,1)

#define FOR(i,n) for(int i=0; i<n; i++)

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;

#define pb push_back
#define mp make_pair
#define F first
#define S second

const int OO = 1e9;

// end of macro

const int N = 1e5+10;
int SRC, SINK, n, m;

struct edge{int to, flow, cap, cost;};
vector<edge>edges;
vi lse[N];

void addEdge(int a, int b, int cap, int cost){
    lse[a].pb(edges.size());
    edges.pb({b, 0, cap, cost});
    lse[b].pb(edges.size());
    edges.pb({a, 0, 0, -cost}); // here cap=0, cannot make 2 way, have to call this function twice, because of cost
}

int level[N]; // to prevent infinite loop during dfs
int potential[N];
int dist[N];
int lastEdge[N];

int ccost(int now, edge& e){ // compute cost w/ potentials
    return e.cost + potential[now] - potential[e.to];
}

// almost like dinic's bfs, but dijkstra instead
bool dijkstra(){

	REP(i,1,n) {
		potential[i] += dist[i];
		dist[i] = -1;
		level[i] = 0;
	}

    priority_queue<pii>pq;

    level[SRC] = 0;
    pq.push(mp(0, SRC));
    dist[SRC] = 0;
    while(!pq.empty()){
        int d = -pq.top().F;
        int now = pq.top().S;
        pq.pop();
        if(dist[now] != d)continue;

        FOR(i,lse[now].size()){

            edge& e = edges[lse[now][i]];
            if(e.flow < e.cap){
                if(dist[e.to] != -1 && dist[e.to] <= d+ccost(now, e))continue;
                dist[e.to] = d+ccost(now, e);
                level[e.to] = max(level[e.to], level[now]+1);
                pq.push(mp(-d-ccost(now, e), e.to));
            }
        }
    }
    return dist[SINK] != -1;
}

int dfs(int now, int flow){ // do the flow
    if(now == SINK)return flow;

    //printf("at %d, flow %d
",now,flow);

    int ret = 0;
    for(int& i = lastEdge[now]; i<lse[now].size(); i++){
        edge& e = edges[lse[now][i]];
        if(level[e.to] <= level[now])continue; //going back
        if(e.flow == e.cap)continue; // no flow
        if(dist[e.to] == dist[now] + ccost(now, e)){
        	//printf("%d -> %d
",now,e.to);
            int curr = dfs(e.to, min(flow, e.cap - e.flow));
            if(curr > 0){
                e.flow += curr; // forward flow
                edges[lse[now][i]^1].flow -= curr; // residual
                flow -= curr;
                ret += curr;
                if(flow == 0)return ret; // if flow to this node is already depleted, i.e. there is a bottleneck far before this node
            }
        }
    }
    return ret;
}


int totalflow, totalcost;
void MCMF(){
    totalflow = totalcost = 0;
    while(dijkstra()) {
    	//printf("dist %d
",dist[SINK] + potential[SINK]);
    	//REP(i,1,n*m)printf("%d = %d
",i,dist[i]+potential[i]);
		REP(i,1,n) lastEdge[i]=0;
		lastEdge[SRC]=lastEdge[SINK]=0;
        int flow = dfs(SRC, OO);
        totalflow += flow;
        totalcost += flow * (dist[SINK] + potential[SINK]);
    }
}

int main() {
    scanf("%d%d%d%d", &n, &m, &SRC, &SINK);
    REP(i,1,m) {
        int u,v,w,f;
        scanf("%d%d%d%d",&u,&v,&w,&f);
        addEdge(u,v,w,f);
    }
    MCMF();
    printf("%d %d
",totalflow,totalcost);
}
原文地址:https://www.cnblogs.com/uid001/p/11070064.html