• 最小费用最大流模板


    题目描述
    如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用。
    输入输出格式
    输入格式:
    第一行包含四个正整数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 }
    递归版
  • 相关阅读:
    Java项目xml相关配置
    Jquery的bind跟on绑定事件的区别
    命令操作Mysql数据库
    Jquery实现功能---购物车
    Jquery插件---渐隐轮播
    Jquery制作插件---内容切换
    PCB画板的快捷键
    蓝牙2.0传数据给数码管
    蓝牙2.0传数据给数码管
    共阳极数码管计数器
  • 原文地址:https://www.cnblogs.com/adelalove/p/8705517.html
Copyright © 2020-2023  润新知