• [网络流24题]运输问题


    原题链接:https://www.luogu.org/problemnew/show/P4015

    会写费用流了好开心啊。。。

    题意简述:有m个仓库,第i个仓库有a[i]个货物,n个商店,第i个商店需要b[i]件货物。

    第i个仓库向第j个商店运一件货物的价格为d[i][j]。

    求最少花费。

    费用流板子题。

    1-m表示仓库,m+1-m+n表示商店。

    源点向仓库连流量为a[i],费用0,商店向汇点连边,流量b[i],费用0

    第i个仓库向第j个商店连边,费用d[i][j],流量>=a[i]即可

    非常直接的建边方式。。。然后就是费用流板子了

    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int inf=2147483647;
    void read(int &y)
    {
        y=0;char x=getchar();
        int f=1;
        while(x<'0'||x>'9') x=getchar();
        while(x>='0'&&x<='9')
        {
            y=y*10+x-'0';
            x=getchar();
        }
    }
    struct edge
    {
        int u,v,w,c;
        int frm;
    }e[100005];
    int m,n,s,cnt=1,t=201;
    int fr[1005],head[2005],vis[2005],dis[2005];
    int a[1005],b[1005];
    int d[105][105];
    long long ans;
    void add(int u,int v,int w,int c)
    {
        e[++cnt].u=head[u];e[cnt].v=v;
        e[cnt].w=w;e[cnt].c=c;
        e[cnt].frm=u;head[u]=cnt;
        
        e[++cnt].u=head[v];e[cnt].v=u;
        e[cnt].w=0;e[cnt].c=-c;
        e[cnt].frm=v;head[v]=cnt;
    }
    int dfs()
    {
        int re=0,x=inf;
        for(int i=fr[t];i;i=fr[e[i].frm]) x=min(e[i].w,x);
        for(int i=fr[t];i;i=fr[e[i].frm])
        {
            e[i].w-=x;
            e[i^1].w+=x;
            re+=x*e[i].c;
        }
        return re;
    }
    int spfa()
    {
        for(int i=1;i<=t;i++) dis[i]=inf;
        memset(vis,0,sizeof(vis));
        queue<int>q;
        q.push(s);
        vis[s]=1;dis[s]=0;
        while(!q.empty())
        {
            int nxt=q.front();q.pop();
            for(int i=head[nxt];i!=-1;i=e[i].u)
            {
                int tmp=e[i].v;
                if(dis[tmp]>dis[nxt]+e[i].c&&e[i].w)
                {
                    dis[tmp]=dis[nxt]+e[i].c;
                    fr[tmp]=i;
                    if(vis[tmp]==0)
                    {
                        vis[tmp]=1;
                        q.push(tmp);
                    }
                }
            }
            vis[nxt]=0;
            
        }
        if(dis[t]==inf) return 0;
        return 1;
    }
    int main()
    {
        read(m);read(n);
        for(int i=1;i<=m;i++) read(a[i]);
        for(int i=1;i<=n;i++) read(b[i]);
        int x;
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=n;j++) read(d[i][j]);
        }
        memset(head,-1,sizeof(head));
        for(int i=1;i<=m;i++) add(s,i,a[i],0);
        for(int i=1;i<=n;i++) add(m+i,t,b[i],0);
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=n;j++) add(i,m+j,inf,d[i][j]);
        }
        while(spfa()) ans+=dfs();
        printf("%lld
    ",ans);
        memset(head,-1,sizeof(head));
        cnt=1;ans=0;
        for(int i=1;i<=m;i++) add(s,i,a[i],0);
        for(int i=1;i<=n;i++) add(m+i,t,b[i],0);
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=n;j++) add(i,m+j,inf,-d[i][j]);
        }
        while(spfa()) ans+=dfs();
        printf("%lld",-ans);
        return 0;
    }
  • 相关阅读:
    OL8.0静默安装Oracle 19C
    MYSQL GTID 复制
    MYSQL异步复制
    YUM方式安装MYSQL5.7
    【学习笔记】大数据技术原理与应用(MOOC视频、厦门大学林子雨)
    【网友的】《一个程序猿的生命周期》读后感
    连载《一个程序猿的生命周期》-22.缺了一条腿的公司
    续评《遇到一位ITer,一位出租车司机,必看》
    遇到一位ITer,一位出租车司机,必看。
    连载《一个程序猿的生命周期》-21.而立之年,第一次跳槽,寻求转型
  • 原文地址:https://www.cnblogs.com/zeroform/p/8507943.html
Copyright © 2020-2023  润新知