• 网络流板子


    最大流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);
    }
    
  • 相关阅读:
    SQL Server 损坏修复
    记录一些数据库函数或全局变量
    查询数据库空间使用情况
    SQL Server 2008文件与文件组的关系
    大型网站--负载均衡架构
    本地事务和分布式事务工作实践
    IIS防止同一IP大量非法访问
    使用EventLog类写Windows事件日志
    1878: [SDOI2009]HH的项链
    模板
  • 原文地址:https://www.cnblogs.com/uid001/p/11070064.html
Copyright © 2020-2023  润新知