• poj 2516 Minimum Cost 夜


    http://poj.org/problem?id=2516

    此题和2195题是一个题型

    不同之处在于此题需要对每种物品均求一次最小花费然后合计

    而且每种物品 还要看是否满足了需求量 有一种物品不满足的话就输出-1

    我的方法很笨 依次对每种物品进行求解

    而且由于流很小 我直接用了每次流都是减一 下个题应该就不行了(我猜)

    详情见代码注释

    #include<iostream>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<cstdio>
    
    using namespace std;
    const int N=105;
    const int M=100000005;
    int have[N][N];//应有者对第几种物品的供应量
    int need[N][N];//需求者对第几中物品的需求量
    int goodpay[N][N][N];//第几种物品传送的单位花费
    int flow[N][N];//流量 需要对不同的物品每次更新
    int pay[N][N];//花费 需要对不同的物品每次更新
    int Spfa(int n)
    {
        bool in[N];
        int dist[N];
        int f[N];
        for(int i=1;i<=n;++i)
        {
            dist[i]=M;
        }
        memset(in,false,sizeof(in));
        dist[0]=0;
        queue<int>str;
        in[0]=true;
        str.push(0);
        while(!str.empty())
        {
            int x=str.front();
            str.pop();
            in[x]=false;//cout<<x<<endl;
            for(int i=1;i<=n;++i)
            {
                if(flow[x][i]>0&&dist[i]>dist[x]+pay[x][i])
                {
                    dist[i]=dist[x]+pay[x][i];//每次只计算一个流的花费 流不会太多 所以时间没问题 
                    f[i]=x;
                    if(in[i]==false)
                    {
                        in[i]=true;
                        str.push(i);
                    }
                }
            }
        }//cout<<dist[n]<<endl;
        if(dist[n]==M)
        return 0;
        int k=n;
        while(k!=0)
        {
            int pre=f[k];
            flow[pre][k]--;//只计算了一个流的花费 所以也个更新一个流
            flow[k][pre]++;
            k=pre;
        }
        return dist[n];
    
    }
    int Addpay(int n,int m,int k)
    {
        memset(flow,0,sizeof(flow));
        memset(pay,0,sizeof(pay));
        for(int i=1;i<=m;++i)//对超级源点到供应者的流进行限制
        {
            flow[0][i]=have[i][k];
        }
        int sum=0;
        for(int i=1;i<=n;++i)//对需求者到超级终极进行流的限制
        {
            flow[i+m][n+m+1]=need[i][k];
            sum=sum+need[i][k];
        }
        for(int i=1;i<=m;++i)
        {
            for(int j=1;j<=n;++j)
            {
                flow[i][j+m]=min(have[i][k],need[j][k]);//对供应者到需求者之间的流进行限制
                pay[i][j+m]=goodpay[k][i][j];//花费统计
                pay[j+m][i]=-pay[i][j+m];//反向花费取负
            }
        }
        int MIN=0;//总花费统计
        int X=0;
        while(1)
        {
            int k=Spfa(n+m+1);
            if(k==0)
            break ;
            MIN+=k;
            X=X+1;//流每次加一
        }
        if(X==sum)//总流是否满足总需求流的量
        return MIN;
        return -1;
    }
    int main()
    {
        int n,m,k;
        while(scanf("%d %d %d",&n,&m,&k)!=EOF)
        {
            if(n==0&&m==0&&k==0)
            break;
            for(int i=1;i<=n;++i)
            {
                for(int j=1;j<=k;++j)
                {
                    scanf("%d",&need[i][j]);
                }
            }
            for(int i=1;i<=m;++i)
            {
                for(int j=1;j<=k;++j)
                {
                    scanf("%d",&have[i][j]);
                }
            }
            for(int l=1;l<=k;++l)
            {
                for(int i=1;i<=n;++i)
                {
                    for(int j=1;j<=m;++j)
                    {
                        scanf("%d",&goodpay[l][j][i]);
                    }
                }
            }
            int ans=0;
            for(int i=1;i<=k;++i)
            {
                int q=Addpay(n,m,i);//如果哪次物品没满足需求直接-1
                if(q==-1)
                {
                    ans=-1;break;
                }
                else
                {
                    ans=ans+q;
                }
            }
            printf("%d\n",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    模拟75 题解
    模拟74 题解
    模拟73 题解
    模拟72 题解
    前端学习:html基础学习二
    前端学习:html基础学习一
    JavaScrip:Function函数编程
    MYSQL:RELPACE用法
    MYSQL:插入记录检查记录是否存在,存在则更新,不存在测插入记录SQL
    OpenCASCADE Curve Length Calculation
  • 原文地址:https://www.cnblogs.com/liulangye/p/2517140.html
Copyright © 2020-2023  润新知