zoukankan      html  css  js  c++  java
  • 最小费用最大流

    题目描述

    如题,给出一个网络图,以及其源点和汇点,每条边已知其最大流量和单位流量费用,求出其网络最大流和在最大流情况下的最小费用。

    输入输出格式

    输入格式:

    第一行包含四个正整数N、M、S、T,分别表示点的个数、有向边的个数、源点序号、汇点序号。

    接下来M行每行包含四个正整数ui、vi、wi、fi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi),单位流量的费用为fi。

    输出格式:

    一行,包含两个整数,依次为最大流量和在最大流量情况下的最小费用。

    输入输出样例

    输入样例#1:
    4 5 4 3
    4 2 30 2
    4 3 20 3
    2 3 20 1
    2 1 30 9
    1 3 40 5
    输出样例#1:
    50 280

    说明

    时空限制:1000ms,128M

    (BYX:最后两个点改成了1200ms)

    数据规模:

    对于30%的数据:N<=10,M<=10

    对于70%的数据:N<=1000,M<=1000

    对于100%的数据:N<=5000,M<=50000

    样例说明:

    如图,最优方案如下:

    第一条流为4-->3,流量为20,费用为3*20=60。

    第二条流为4-->2-->3,流量为20,费用为(2+1)*20=60。

    第三条流为4-->2-->1-->3,流量为10,费用为(2+9+5)*10=160。

    故最大流量为50,在此状况下最小费用为60+60+160=280。

    故输出50 280。

    spfa费用流

    #include<queue>
    #include<cstdio>
    #include<cstring> 
    #include<algorithm>
    using namespace std;
    const int maxn = 4*50000;
    inline int read()
    {
        int x=0,f=1;char c= getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c-'0');c=getchar();}
        return f*x;
    }
    struct node{
        int u,v,cost,flow,next;
    }edge[maxn];
    int head[maxn],num=1,n,m,s,t;
    int min_cost=0,max_flow=0;
    int dis[maxn],pre[maxn];
    bool vis[maxn];
    inline void add_edge(int x,int y,int z,int c)
    {    
        edge[++num].v=y;edge[num].u=x;edge[num].flow=z;edge[num].cost=c;edge[num].next=head[x];head[x]=num;
    }
    bool spfa()
    {
        memset(dis,0x3f,sizeof dis);
        memset(vis,0,sizeof vis);
        vis[s]=1;
        dis[s]=0;
        queue<int>que;
        que.push(s);
        while(!que.empty())
        {
            int u=que.front();
            que.pop();
            for(int i=head[u];i;i=edge[i].next)
            {
                int v=edge[i].v;
                if(dis[u]+edge[i].cost<dis[v]&&edge[i].flow>0)
                {
                    dis[v]=edge[i].cost+dis[u];
                    pre[v]=i;
                    if(!vis[v])
                    {
                        que.push(v);
                        vis[v]=1;
                    }
                }
            }
            vis[u]=0;
        }
        if(dis[t]==0x3f3f3f3f)return 0;
        else return 1;
    }
    void work()
    {
        int ma=0x3f3f3f3f;
        for(int i=t;i!=s;i=edge[pre[i]].u)
            ma=min(edge[pre[i]].flow,ma);
        for(int i=t;i!=s;i=edge[pre[i]].u)
        {
            edge[pre[i]].flow-=ma;
            edge[pre[i]^1].flow+=ma;
            min_cost+=(ma*edge[pre[i]].cost);
        }
        max_flow+=ma;
    }
    void miku()
    {
        while(spfa())
            work();
    }
    int main()
    {
        n=read(),m=read(),s=read(),t=read();
        int a,b,c,d;
        while(m--)
        {
            a=read(),b=read(),c=read(),d=read();
            add_edge(a,b,c,d);
            add_edge(b,a,0,-d);
        }
        miku();
        printf("%d %d
    ",max_flow,min_cost);
        return 0;
    }
  • 相关阅读:
    LeetCode 264. Ugly Number II
    LeetCode 231. Power of Two
    LeetCode 263. Ugly Number
    LeetCode 136. Single Number
    LeetCode 69. Sqrt(x)
    LeetCode 66. Plus One
    LeetCode 70. Climbing Stairs
    LeetCode 628. Maximum Product of Three Numbers
    Leetcode 13. Roman to Integer
    大二暑假周进度报告03
  • 原文地址:https://www.cnblogs.com/sssy/p/7263911.html
Copyright © 2011-2022 走看看