最小费用最大流模板

题目描述
如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用。
输入输出格式
输入格式:
第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。
接下来M行每行包含四个正整数ui、vi、wi、fi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi),单位流量的费用为fi。
输出格式:
一行,包含两个整数,依次为最大流量和在最大流量情况下的最小费用。
输入输出样例
输入样例#14 5 4 3
4 2 30 2
4 3 20 3
2 3 20 1
2 1 30 9
1 3 40 5
输出样例#150 280
说明
时空限制:1000ms,128M
(BYX:最后两个点改成了1200ms)
数据规模:
对于30%的数据:N<=10,M<=10
对于70%的数据:N<=1000,M<=1000
对于100%的数据:N<=5000,M<=50000
大部分题面

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+10;
struct node{
    int u,v,fl,c,ne;
}e[N*2];
int h[N],tot,n,m;
void add1(int u,int v,int fl,int c)
{
    tot++;e[tot]=(node){u,v,fl,c,h[u]};h[u]=tot;
}
void add(int u,int v,int fl,int c)
{
    add1(u,v,fl,c);add1(v,u,0,-c);
}
queue<int>q;
int d[N],S,T,pre[N],v[N];
bool spfa()
{
    for(int i=1;i<=n;++i) 
     d[i]=1e9,pre[i]=0,v[i]=0;
    d[S]=0;q.push(S);v[S]=1;
    while(!q.empty())
    {
        int ff=q.front();q.pop();v[ff]=0;
        for(int i=h[ff];i;i=e[i].ne)
        {
            int rr=e[i].v;
            if(e[i].fl && d[rr]>d[ff]+e[i].c)
            {
                 d[rr]=d[ff]+e[i].c;pre[rr]=i;
                 if(!v[rr]) q.push(rr),v[rr]=1;
            }
        }
    }
    return d[T]<1e9;
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&S,&T);
    tot=1;
    for(int i=1,x,y,z,w;i<=m;++i)
    {
        scanf("%d%d%d%d",&x,&y,&w,&z);
        add(x,y,w,z);
    }
    ll ans1=0,ans2=0;
    while(spfa())
    {
        int Min=1e9;
        for(int i=T;i!=S;i=e[pre[i]].u)
         Min=min(Min,e[pre[i]].fl);
        for(int i=T;i!=S;i=e[pre[i]].u)
         e[pre[i]].fl-=Min,e[pre[i]^1].fl+=Min;
        ans1+=Min;ans2+=1ll*Min*d[T];
    }
    cout<<ans1<<" "<<ans2;
    return 0;
}
非递归版

 

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N=1e5+10;
 5 struct node{
 6     int u,v,fl,c,ne;
 7 }e[N*2];
 8 int h[N],tot,n,m;
 9 void add1(int u,int v,int fl,int c)
10 {
11     tot++;e[tot]=(node){u,v,fl,c,h[u]};h[u]=tot;
12 }
13 void add(int u,int v,int fl,int c)
14 {
15     add1(u,v,fl,c);add1(v,u,0,-c);
16 }
17 queue<int>q;
18 int d[N],S,T,H[N],v[N];
19 bool spfa()
20 {
21     for(int i=1;i<=n;++i) d[i]=1e9,v[i]=0;
22     d[S]=0;q.push(S);v[S]=1;
23     while(!q.empty())
24     {
25         int ff=q.front();q.pop();v[ff]=0;
26         for(int i=h[ff];i;i=e[i].ne)
27         {
28             int rr=e[i].v;
29             if(e[i].fl && d[rr]>d[ff]+e[i].c)
30             {
31                  d[rr]=d[ff]+e[i].c;
32                  if(!v[rr]) q.push(rr),v[rr]=1;
33             }
34         }
35     }
36     return d[T]<1e9;
37 }
38 int dfs(int u,int fl)
39 {
40     v[u]=1;
41     if(u==T || fl==0) return fl;
42     int get=0,f;
43     for(int i=H[u];i;i=e[i].ne)
44     {
45         int rr=e[i].v;
46         if(e[i].fl && d[rr]==d[u]+e[i].c && !v[rr])
47         {
48             f=dfs(rr,min(fl,e[i].fl));
49             if(!f) continue;
50             get+=f;fl-=f;
51             e[i].fl-=f;e[i^1].fl+=f;
52             H[u]=i;
53             if(fl==0) break;
54         }
55     }
56     if(get==0) d[u]=1e9;
57     return get;
58 }
59 int main()
60 {
61     scanf("%d%d%d%d",&n,&m,&S,&T);
62     tot=1;
63     for(int i=1,x,y,z,w;i<=m;++i)
64     {
65         scanf("%d%d%d%d",&x,&y,&w,&z);
66         add(x,y,w,z);
67     }
68     ll ans1=0,ans2=0;
69     while(spfa())
70     {
71         v[T]=1;
72         while(v[T])
73         {
74             for(int i=1;i<=n;++i) H[i]=h[i],v[i]=0;
75             int nw=dfs(S,1e9);
76             ans1+=nw;ans2+=d[T]*nw;
77         }
78     }
79     cout<<ans1<<" "<<ans2;
80     return 0;
81 }
递归版

 

posted @ 2018-04-03 06:20  月亮茶  阅读(106)  评论(0编辑  收藏  举报