最小费用最大流/费用流zkw算法模板(洛谷3381)

来源:互联网 发布:淘宝网千人千面 编辑:程序博客网 时间:2024/05/29 19:59
#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<algorithm>#define rep(i,a,b) for(int i=a;i<=b;i++)#define dep(i,a,b) for(int i=a;i>=b;i--)#define ll long long#define inf 1000000000#define mem(x,num) memset(x,num,sizeof x)#define reg(x) for(int i=last[x];i;i=e[i].next)using namespace std;inline ll read(){    ll f=1,x=0;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}const int maxm=1e6+6;int S,T,ans,n,m,k,cnt=1,que[maxm],d[maxm],last[maxm];bool inq[maxm];struct edge{int to,next,v,c;}e[maxm<<2];void insert(int u,int v,int w,int c){    e[++cnt]=(edge){v,last[u],w,c};last[u]=cnt;    e[++cnt]=(edge){u,last[v],0,-c};last[v]=cnt;}bool spfa(int S,int T){    mem(inq,0);    int head=0,tail=1,now;    rep(i,0,n)d[i]=inf;    que[0]=T;d[T]=0;inq[T]=1;    while(head<tail){        now=que[head++];        reg(now)            if(e[i^1].v&&d[now]-e[i].c<d[e[i].to]){                d[e[i].to]=d[now]-e[i].c;                if(!inq[e[i].to])inq[e[i].to]=1,que[tail++]=e[i].to;        }        inq[now]=0;    }    if(d[S]!=inf)return 1;else return 0;}int dfs(int x,int f){    if(x==T)return f;    int used=0,w;inq[x]=1;    reg(x)        if(!inq[e[i].to]&&e[i].v&&d[x]-e[i].c==d[e[i].to]){            w=dfs(e[i].to,min(e[i].v,f-used));            if(w)ans+=w*e[i].c,e[i].v-=w,e[i^1].v+=w,used+=w;            if(used==f)return f;        }    return used;}void zkw(){    int flow=0;    while(spfa(S,T)){        inq[T]=1;        while(inq[T]){mem(inq,0);flow+=dfs(S,inf);}    }    cout<<flow<<' '<<ans<<endl;}int main(){    n=read(),m=read(),S=read(),T=read();    rep(i,1,m){        int u=read(),v=read(),w=read(),c=read();        insert(u,v,w,c);    }    zkw();    return 0;}
原创粉丝点击