dinic 最大流費用流模板

 

dinic最大流:

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i = (int)a;i<=(int)b;i++)
#define pb push_back
#define lson rt<<1
#define rson rt<<1|1
#define mid (l+r)/2
using namespace std;
const int maxn=200005;
const int maxm=2000005;
const int MAX = 1<<26;
typedef long long ll;
typedef pair<int,int> pii;
int nex[maxm],to[maxm],cap[maxm],from[maxm];
int n,m,cnt,head[maxn],d[maxn],sp,tp;//原點,匯點
//理論複雜度n2*m
void add(int u,int v,int c){
    from[cnt]=u,to[cnt]=v,cap[cnt]=c,nex[cnt]=head[u],head[u]=cnt++;
    from[cnt]=v,to[cnt]=u,cap[cnt]=0,nex[cnt]=head[v],head[v]=cnt++;
}
int bfs(){
    queue <int> q;
    memset(d,-1,sizeof(d));
    d[sp]=0;
    q.push(sp);
    while(!q.empty()){
        int cur=q.front();
        q.pop();
        for(int i=head[cur];i!=-1;i=nex[i]){
            int u=to[i];
            if(d[u]==-1 && cap[i]>0){
                d[u]=d[cur]+1;
                q.push(u);
            }
        }
    }
    return d[tp] != -1;
}
int dfs(int a,int b){
    int r=0;
    if(a==tp)return b;
    for(int i=head[a];i!=-1 && r<b;i=nex[i])
    {
        int u=to[i];
        if(cap[i]>0 && d[u]==d[a]+1)
        {
            int x=min(cap[i],b-r);
            x=dfs(u,x);
            r+=x;
            cap[i]-=x;
            cap[i^1]+=x;
        }
    }
    if(!r)d[a]=-2;
    return r;
}

int dinic(int sp,int tp){
    int total=0,t;
    while(bfs()){
        while(t=dfs(sp,MAX))
        total+=t;
    }
    return total;
}
int main(){
    int i,u,v,c,x;
    cnt=0;
    memset(head,-1,sizeof(head));




    return 0;
}


EK費用流

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=400000;
const int maxm=1000000;
const int inf=0x3f3f3f3f;
int dis[maxn];
int vis[maxn],pre[maxn];
int head[maxn],cnt;
int n,m,sp,tp;
ll ans=0;
struct node{
    int to,cap,cost,next;
}e[maxm];
void add(int from,int to,int cap,int cost){
    e[cnt].to=to; e[cnt].cap=cap;
    e[cnt].cost=cost; e[cnt].next=head[from];
    head[from]=cnt++;
 
    e[cnt].to=from; e[cnt].cap=0;
    e[cnt].cost=-cost; e[cnt].next=head[to];
    head[to]=cnt++;
}
bool spfa(int s,int t,int &flow,int &cost){
    queue<int> q;
    memset(dis,inf,sizeof(dis));
    memset(vis,0,sizeof(vis));
    memset(pre,-1,sizeof(pre));
    dis[s]=0;  q.push(s);
    vis[s]=1;
    int d=inf;
    while(!q.empty()){
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];~i;i=e[i].next){
            int v=e[i].to;
            if(e[i].cap>0&&dis[v]>dis[u]+e[i].cost){
                dis[v]=dis[u]+e[i].cost;
                pre[v]=i;
                if(!vis[v]){
                    vis[v]=1;
                    q.push(v);
                }
            }
        }
    }
    if(dis[t]==inf){
        return false;
    }
    for(int i=pre[t];~i;i=pre[e[i^1].to]){
        d=min(d,e[i].cap);
    }
    for(int i=pre[t];~i;i=pre[e[i^1].to]){
        e[i].cap-=d;
        e[i^1].cap+=d;
        cost+=e[i].cost*d;
    }
    flow+=d;
    return true;
}
int mcmf(int s,int t){
    int flow=0,cost=0;
    while(spfa(s,t,flow,cost)){
        //cout<<flow<<" "<<cost<<endl;
    }
    return cost;
}
int main(){
    memset(head,-1,sizeof(head));
    ans=0;
    scanf("%d",&n);
    sp=0;tp=50001;
    
    cout<<mcmf(sp,tp)<<endl;
    
    return 0;
}

不出意外的dijkstra模板(EK)

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=400000;
const int maxm=1000000;
const int inf=0x3f3f3f3f;
int dis[maxn];
int vis[maxn],pre[maxn];
int head[maxn],cnt,h[maxn],tmpc[maxn];
int to[maxm],cap[maxm],cost[maxm],nex[maxm];
int n,m,sp,tp;
ll ans=0;
struct node{
    int dis,id;
    node(){}
    node(int id,int dis):id(id),dis(dis){}
    bool operator < (const node &a)const{
        return dis>a.dis;
    }
};
void add(int ffrom,int tto,int ccap,int ccost){
    to[cnt]=tto; cap[cnt]=ccap;
    cost[cnt]=ccost; nex[cnt]=head[ffrom];
    head[ffrom]=cnt++;

    to[cnt]=ffrom; cap[cnt]=0;
    cost[cnt]=-ccost; nex[cnt]=head[tto];
    head[tto]=cnt++;
}
bool Dijkstra(int s,int t,int &flow,int &tmpcost,int n){
    priority_queue<pii ,vector<pii> ,greater<pii> > Q;
    for(int i=1;i<=n;i++){
        dis[i]=inf;
        vis[i]=0;
        pre[i]=-1;
    }
    dis[s]=0;  Q.push({0,s});
    vis[s]=1;  tmpc[s]=inf;

    while(!Q.empty()){
        pii tmp= Q.top(); Q.pop();
        int u=tmp.second;
        if(dis[u]<tmp.first) continue;

        for(int i=head[u];~i;i=nex[i]){
            int v=to[i];
            if(cap[i]>0&&dis[v]>dis[u]+cost[i]+h[u]-h[v]){
                dis[v]=dis[u]+cost[i]+h[u]-h[v];
                pre[v]=i; tmpc[v]=min(cap[i],tmpc[u]);
                Q.push({dis[v],v});
            }
        }
    }
    if(dis[t]==inf){
        return false;
    }
    for(int i=1;i<=n;i++){
        if(dis[i]<inf) h[i]+=dis[i];
    }
    int d=tmpc[t];

    for(int i=pre[t];~i;i=pre[to[i^1]]){
        cap[i]-=d;
        cap[i^1]+=d;
    }
    flow+=d;
    tmpcost+=h[t]*d;
    return true;
}
int mcmf(int s,int t,int nn){
    int flow=0,cost=0;
    while(Dijkstra(s,t,flow,cost,nn)){
        //cout<<flow<<" "<<cost<<endl;
    }
    return cost;
}
int main(){
    memset(head,-1,sizeof(head));
    ans=0;
    scanf("%d",&n);
    sp=0;tp=50001;

    cout<<mcmf(sp,tp,n)<<endl;

    return 0;
}

zkw費用流

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i = (int)a;i<=(int)b;i++)
#define rep_e(i,u,v) for(int i=head[u],v=to[i];~i;i=nex[i],v=to[i])
using namespace std;
typedef long long ll;
const int maxn=100005;
const int maxm=200005;
const int inf=1e9+7;
bool vis[maxn];
int dist[maxn],sp,tp,n,m;
int head[maxn],to[maxm],nex[maxm],cap[maxm],cost[maxm],cnt;
void add(int u,int v,int Cap,int Cost){
    to[cnt]=v; nex[cnt]=head[u]; cap[cnt]=Cap; cost[cnt]=Cost; head[u]=cnt++;
    to[cnt]=u; nex[cnt]=head[v]; cap[cnt]=0; cost[cnt]=-Cost; head[v]=cnt++;
}
inline bool Spfa(int s,int t){
    memset(vis,0,sizeof(vis));

    rep(i,0,n){
        dist[i]=inf;
    }
    dist[t]=0,vis[t]=1;
    deque<int> q;
    q.push_back(t);
    while(!q.empty()){
        int u=q.front(); q.pop_front();
        for(int i=head[u];~i;i=nex[i]){
            int v=to[i];

            if(cap[i^1]&&dist[v]>dist[u]-cost[i]){
                dist[v]=dist[u]-cost[i];
                if(!vis[v]){
                    vis[v]=1;
                    if(!q.empty()&&dist[v]<dist[q.front()])
                        q.push_front(v);
                    else q.push_back(v);
                }
            }
        }
        vis[u]=0;
    }
    return dist[s]<inf;
}
inline int dfs(int u,int low,int &Cost){
    if(u==tp){
        vis[tp]=1;
        return low;
    }
    int used=0,flow;
    vis[u]=1;
    for(int i=head[u];~i;i=nex[i]){
        int v=to[i];
        if(!vis[v]&&cap[i]&&dist[u]-cost[i]==dist[v]){
            flow=dfs(v,min(cap[i],low-used),Cost);
            if(flow) {
                Cost+=flow*cost[i];
                cap[i]-=flow; cap[i^1]+=flow;
                used+=flow;
            }
            if(used==low) break;
        }
    }
    return used;
}
inline int mcmf(int sp,int tp,int &flow){
    flow=0;
    int Cost=0;
    while(Spfa(sp,tp)){
        vis[tp]=1;
        while(vis[tp]){
            memset(vis,0,sizeof(vis));
            flow+=dfs(sp,inf,Cost);
        }
    }
    return Cost;
}
int main(){
    memset(head,-1,sizeof(head));
    scanf("%d%d%d%d",&n,&m,&sp,&tp);
    rep(i,1,m){
        int u,v,ca,co; scanf("%d%d%d%d",&u,&v,&ca,&co);
        add(u,v,ca,co);
    }
    int flow;
    int costs=mcmf(sp,tp,flow);
    printf("%d %d\n",flow,costs);
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章