#102. 最小费用流

来源:互联网 发布:云豹直播源码破解版 编辑:程序博客网 时间:2024/05/21 17:49

Problem A: #102. 最小费用流

Time Limit: 5 Sec  Memory Limit: 256 MB
Submit: 10  Solved: 5
[Submit][Status][Web Board]

Description

这是一道模板题。

给定一个图,每条边有容量和费用,使用每条边的单位流量需要支付特定的费用。给定源点 1 和汇点n,求图的最大流和最大流需要支付的最小费用。

Input

第一行两个整数 n m,表示有n 个点m 条边。

从第二行开始的之后 m  行,每行四个整数siticiwi 表示一条从si 到ti 的边,容量为ci,单位流量需要支付的费用为wi

Output

一行两个整数,分别表示最大流和最大流需要支付的最小费用。

Sample Input

8 23
2 3 2147483647 1
1 3 1 1
2 4 2147483647 2
1 4 1 2
2 8 2 0
3 5 2147483647 3
1 5 1 3
3 6 2147483647 4
1 6 1 4
3 8 2 0
3 2 2147483647 0
4 6 2147483647 5
1 6 1 5
4 7 2147483647 6
1 7 1 6
4 8 2 0
4 2 2147483647 0
5 8 0 0
5 2 2147483647 0
6 8 0 0
6 2 2147483647 0
7 8 0 0
7 2 2147483647 0

Sample Output

6 24

HINT

1≤n≤400,0≤m≤15000 ,保证输入数据、中间结果以及答案在 32 位有符号整数范围内。


#include<cstdio>#include<cstring>const int maxn=1e4+10;const int maxm=1e5+10;const int maxt=2139062143;inline int min_(int x,int y){return x<y?x:y;}int n,m,s,t,nflow,nfee,flow,fee;int a,b,c,d;int h[maxn],hs=1;int e_q[maxm],e_z[maxm],e_n[maxm],e_w[maxm],e_f[maxm];int add(int q,int z,int k,int w,int f){e_q[k]=q,e_z[k]=z,e_n[k]=h[q],e_w[k]=w,e_f[k]=f,h[q]=k;}int q[maxm],head,tail;int w[maxn],p[maxn];bool v[maxn];int ap(int k,int v){    if(k==s) return v;    int ret=ap(e_q[p[k]],min_(v,e_w[p[k]]));    if(!e_f[p[k]^1]) add(k,e_q[p[k]],p[k]^1,0,-e_f[p[k]]);    e_w[p[k]]-=ret,e_w[p[k]^1]+=ret;    return ret;} void Mcmf(){    while(1){        memset(w,0x7f,sizeof(w));        memset(v,0,sizeof(v));        head=tail=w[s]=0;        q[head++]=s,v[s]=1;        while(head>tail){            a=q[tail++],v[a]=0;            for(int i=h[a];i;i=e_n[i])            if(0ll+e_f[i]+w[a]<w[e_z[i]]&&e_w[i]){                p[e_z[i]]=i;                w[e_z[i]]=e_f[i]+w[a];                if(!v[e_z[i]]) q[head++]=e_z[i],v[e_z[i]]=1;            }        }        if(w[t]==maxt) break;        nflow=ap(t,maxt);        flow+=nflow;        fee+=nflow*w[t];    }}int main(){    scanf("%d%d%d%d",&n,&m,&s,&t);    for(int i=1;i<=m;i++){        scanf("%d%d%d%d",&a,&b,&c,&d);        ++hs,add(a,b,hs,c,d),hs++;    }    Mcmf();    printf("%d %d\n",flow,fee);    return 0;}


原创粉丝点击