zoukankan      html  css  js  c++  java
  • 洛谷P3381

    原题链接

    题意简述

    模板题啦~

    题解

    每次都以费用作为边权求一下最短路,然后沿着最短路增广。

    Code

    //【模板】最小费用最大流
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    inline char gc()
    {
        static char now[1<<16],*S,*T;
        if(S==T) {T=(S=now)+fread(now,1,1<<16,stdin); if(S==T) return EOF;}
        return *S++;
    }
    inline int read()
    {
        int x=0,f=1; char ch=gc();
        while(ch<'0'||'9'<ch) {if(ch=='-') f=-1; ch=gc();}
        while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
        return x*f;
    }
    int const N=5e3+10;
    int const M=5e4+10;
    int const INF=0x3F3F3F3F;
    int n,m,s,t;
    int cnt,h[N];
    struct edge{int v,c,w,nxt;} ed[M<<1];
    void edAdd(int u,int v,int c,int w)
    {
        ++cnt; ed[cnt].v=v,ed[cnt].c=c,ed[cnt].w=w; ed[cnt].nxt=h[u],h[u]=cnt;
        ++cnt; ed[cnt].v=u,ed[cnt].c=0,ed[cnt].w=-w; ed[cnt].nxt=h[v],h[v]=cnt;
    }
    int dst[N],pre[N]; int q[N],op,cl; bool in[N];
    bool SPFA()
    {
        op=cl=0;
        memset(dst,0x3F,sizeof dst);
        memset(pre,0,sizeof pre);
        dst[s]=0; in[q[++cl%N]=s]=true;
        while(op<cl)
        {
            int u=q[++op%N]; in[u]=false;
            for(int i=h[u];i;i=ed[i].nxt)
            {
                int v=ed[i].v,w=ed[i].w;
                if(dst[u]+w<dst[v] && ed[i].c)
                {
                    pre[v]=i; dst[v]=dst[u]+w;
                    if(!in[v]) in[q[++cl%N]=v]=true;
                }
            }
        }
        return dst[t]<INF;
    }
    int main()
    {
        n=read(),m=read(); s=read(),t=read();
        cnt=1;
        for(int i=1;i<=m;i++)
        {
            int u=read(),v=read(),c=read(),w=read();
            edAdd(u,v,c,w);
        }
        int flow=0,cost=0;
        while(SPFA())
        {
            int fl=INF,u=t;
            while(pre[u]) fl=min(fl,ed[pre[u]].c),u=ed[pre[u]^1].v;
            flow+=fl; cost+=fl*dst[t];
            u=t;
            while(pre[u]) ed[pre[u]].c-=fl,ed[pre[u]^1].c+=fl,u=ed[pre[u]^1].v;
        }
        printf("%d %d
    ",flow,cost);
        return 0;
    }
  • 相关阅读:
    【计算机网络】复习集(更新中)
    滑雪 (记忆化搜索)
    橱窗布置
    复制书稿 (dp+贪心)
    8786:方格取数 (多线程dp)
    编辑距离
    8782:乘积最大
    合并石子 (区间dp+前缀和)
    6045:开餐馆
    6049:买书 (完全背包)
  • 原文地址:https://www.cnblogs.com/VisJiao/p/8485761.html
Copyright © 2011-2022 走看看