zoukankan      html  css  js  c++  java
  • poj-2516(最小费用流)

    题意:有n个商店,每个商店有k种货物,每个货物需要a[n][k]个,有m个仓库,每个仓库也有k种货物,每个货物有b[m][k]个,然后k个矩阵,每个矩阵都是n*m的,第i行第j列表示从仓库j到商店i每单位k货物的花费,问你最小的花费满足商店,不行输出-1;

    解题思路:刚开始以为是拆点费用流,然后会超时。。。后面看别人是直接对每一种货物都建图跑费用流,这样就行了,建一个汇点和源点,源点连向仓库,仓库连向商店,商店连向汇点;

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    const int maxn=100500;
    const int inf=0x3f3f3f3f;
    struct Edge
    {
        int next;
        int to;
        int w;
        int cost;
    }edge[maxn];
    int head[maxn],dist[maxn],pre[maxn],path[maxn];
    int cnt,x,y,w,n,m,k;
    int Start,End;
    int a[205][205],b[205][205],c[205][205][205];
    int need[205],sup[205];
    void add(int u,int v,int w,int cost)
    {
       // cout<<u<<" "<<v<<" "<<w<<" "<<cost<<endl;
        edge[cnt].next=head[u];edge[cnt].to=v;
        edge[cnt].w=w;edge[cnt].cost=cost;head[u]=cnt++;
        //建回边
        edge[cnt].next=head[v];edge[cnt].to=u;
        edge[cnt].w=0;edge[cnt].cost=-cost;head[v]=cnt++;
    }
    bool spfa(int s,int t)
    {
        memset(pre,-1,sizeof(pre));
        memset(dist,inf,sizeof(dist));
        dist[s]=0;
        queue<int>q;
        q.push(s);
        while(!q.empty())//不能有环,建图的时候也要注意
        {
            int u=q.front();q.pop();
            for(int i=head[u];i!=-1;i=edge[i].next)
            {
                int v=edge[i].to;
                if(edge[i].w>0&&dist[u]+edge[i].cost<dist[v])//这条路径存在且能被优化
                {
                    dist[v]=dist[u]+edge[i].cost;
                    pre[v]=u;path[v]=i;q.push(v);
                }
            }
        }
        if(pre[t]==-1)
            return false;
        return true;
    }
    int mincost(int s,int t)
    {
        int cost=0;int flow=0;
        while(spfa(s,t))
        {
            int tempflow=inf;
            for(int u=t;u!=s;u=pre[u])//找最小的流量
            {
                if(edge[path[u]].w<tempflow)
                    tempflow=edge[path[u]].w;
            }
            flow+=tempflow;//每增广一次能得到的流量;
           cost+=dist[t]*tempflow;//花费
            //cost+=dist[t];
            for(int u=t;u!=s;u=pre[u])
            {
                edge[path[u]].w-=tempflow;
                edge[path[u]^1].w+=tempflow;
            }
            //cout<<cost<<endl;
        }
        return cost;
    }
    int main()
    {
        while(scanf("%d%d%d",&n,&m,&k)!=EOF)
        {
            memset(need,0,sizeof(need));
            memset(sup,0,sizeof(sup));
            Start=0;End=n+m+1;
            int flag=0;
            if(n==0&&m==0&&k==0)
                break;
            for(int i=1;i<=n;i++)//商店需要的
                for(int j=1;j<=k;j++)
                {
                    scanf("%d",&a[i][j]);
                    need[j]+=a[i][j];
                }
            for(int i=1;i<=m;i++)//仓库提供的
                for(int j=1;j<=k;j++)
                {
                    scanf("%d",&b[i][j]);
                    sup[j]+=b[i][j];
                }
            for(int i=1;i<=k;i++)//最小花费
                for(int j=1;j<=n;j++)
                    for(int l=1;l<=m;l++)
                    scanf("%d",&c[i][j][l]);
            for(int i=1;i<=k;i++)
            {
                if(sup[i]<need[i])
                {
                    flag=1;
                }
            }
            if(flag)
            {
                printf("-1
    ");continue;
            }
            int ans=0;
            for(int i=1;i<=k;i++)
            {
                memset(head,-1,sizeof(head));cnt=0;
                for(int j=1;j<=m;j++)
                    add(Start,j,b[j][i],0);
                for(int j=1;j<=n;j++)
                    add(j+m,End,a[j][i],0);
    
                for(int j=1;j<=n;j++)
                    for(int l=1;l<=m;l++)
                {
                    add(l,j+m,inf,c[i][j][l]);
                }
                ans+=mincost(Start,End);
            }
            printf("%d
    ",ans);
        }
    }
    

      

  • 相关阅读:
    Ajax基本案例详解之$.getjson的实现
    Ajax基本案例详解之$.getjson的实现
    Ajax传递json数据
    Ajax传递json数据
    Ajax基本案例详解之load的实现
    多节点日志数据 数据集成
    crontab 问题分析
    不留文档的某某离开后 审计服务器操作历史
    /cloudmonitor.log 主机监控
    网关会对开发者的接口非业务调用错误做统一处理
  • 原文地址:https://www.cnblogs.com/huangdao/p/9991973.html
Copyright © 2011-2022 走看看