• PIGS 分类: POJ 图论 2015-08-10 09:15 3人阅读 评论(0) 收藏


    PIGS
    Time Limit: 1000MS Memory Limit: 10000K
    Total Submissions: 18209 Accepted: 8277

    Description
    Mirko works on a pig farm that consists of M locked pig-houses and Mirko can’t unlock any pighouse because he doesn’t have the keys. Customers come to the farm one after another. Each of them has keys to some pig-houses and wants to buy a certain number of pigs.
    All data concerning customers planning to visit the farm on that particular day are available to Mirko early in the morning so that he can make a sales-plan in order to maximize the number of pigs sold.
    More precisely, the procedure is as following: the customer arrives, opens all pig-houses to which he has the key, Mirko sells a certain number of pigs from all the unlocked pig-houses to him, and, if Mirko wants, he can redistribute the remaining pigs across the unlocked pig-houses.
    An unlimited number of pigs can be placed in every pig-house.
    Write a program that will find the maximum number of pigs that he can sell on that day.

    Input
    The first line of input contains two integers M and N, 1 <= M <= 1000, 1 <= N <= 100, number of pighouses and number of customers. Pig houses are numbered from 1 to M and customers are numbered from 1 to N.
    The next line contains M integeres, for each pig-house initial number of pigs. The number of pigs in each pig-house is greater or equal to 0 and less or equal to 1000.
    The next N lines contains records about the customers in the following form ( record about the i-th customer is written in the (i+2)-th line):
    A K1 K2 … KA B It means that this customer has key to the pig-houses marked with the numbers K1, K2, …, KA (sorted nondecreasingly ) and that he wants to buy B pigs. Numbers A and B can be equal to 0.

    Output
    The first and only line of the output should contain the number of sold pigs.

    Sample Input

    3 3
    3 1 10
    2 1 2 2
    2 1 3 3
    1 2 6

    Sample Output

    7

    Source
    Croatia OI 2002 Final Exam - First day
    题意:有不同的猪圈,买家手里有着猪圈的钥匙,拥有那个猪圈的钥匙就可以买这个猪圈的猪,怎样安排买猪才能卖出更多的猪;

    #include <map>
    #include <list>
    #include <climits>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <string>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define eps 1e-9
    #define LL long long
    #define PI acos(-1.0)
    #define INF 0x3f3f3f3f
    #define CRR fclose(stdin)
    #define CWW fclose(stdout)
    #define RR freopen("input.txt","r",stdin)
    #define WW freopen("output.txt","w",stdout)
    
    const int Max = 100000;
    
    int cus[110][110];//图的容量
    
    int flow[110][110];//图的流量
    
    int num[1100];//猪的数量
    
    int pre[1100];//前一个买家
    
    int n,m,data;
    
    int t,s;
    
    int ford()//一般增广路算法
    {
        int minflow[110];
        queue<int >Q;
        memset(flow,0,sizeof(flow));
        minflow[0] = INF;
        t=n+1;
        s=0;
        while(1)
        {
            for(int i=0;i<=t;i++)
            {
                pre[i]=-2;
            }
            while(!Q.empty())
            {
                Q.pop();
            }
            pre[0]=-1;
            Q.push(0);
            while(!Q.empty()&&pre[t]==-2)//BFS找增广路
            {
                int v=Q.front();
                int p;
                Q.pop();
                for(int i=0;i<=t;i++)
                {
                    if(pre[i]==-2&&(p=cus[v][i]-flow[v][i]))
                    {
                        pre[i]=v;
                        Q.push(i);
                        minflow[i]=min(minflow[v],p);
                    }
                }
            }
            if(pre[t]==-2)//如果找不到汇点,则说明图中不存在增广路,算法结束
            {
                break;
            }
            for(int i=pre[t],j=t;i!=-1;j=i,i=pre[i])//回溯进行增广
            {
                flow[i][j] +=minflow[t];
                flow[j][i]-=minflow[t];
            }
        }
        int sum=0;
        for(int i=0;i<t;i++)
        {
            sum+=flow[i][t];//每个点到汇点的总和为最大流
        }
        return sum;
    }
    
    int main()
    {
        while(~scanf("%d %d",&m,&n))
        {
            memset(pre,-1,sizeof(pre));
            memset(cus,0,sizeof(cus));
            for(int i=1;i<=m;i++)
            {
                scanf("%d",&num[i]);
            }
            int s;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&data);
                for(int j=0;j<data;j++)
                {
                    scanf("%d",&s);
                    if(pre[s]==-1)//如果这个猪圈之前没有人,则这个人是第一个人,所以与源点之间的容量为猪圈的猪的数量
                    {
                        cus[0][i]+=num[s];
                    }
                    else
                    {
                        cus[pre[s]][i]=INF;//如果已经有人买了,所以他必须在这个人之后买,但两人之间又没有关系,所以容量为INF(无穷大)
                    }
                    pre[s]=i;
                }
                scanf("%d",&cus[i][n+1]);//到汇点的容量为每个人想买猪的数量
            }
            printf("%d
    ",ford());
        }
    
        return 0;
    }
    

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    SQL server 2008 建立新用户
    2021.3.22-刷题 (移位)
    2021.3.17刷题-分割回文串
    2021.3.16 刷题--组合总和||(一种组合下元素不可重复选取)
    2021.3.15刷题-组合总和(元素可重复选取)
    2021.3.14刷题-设计哈希映射
    2021.3.13刷题-用拉链法设计哈希集合
    2021.3.12刷题-验证二叉树的前序序列化
    2021.3.11刷题-(删除二叉搜索树中的节点)
    2021.2.28刷题 回溯-电话字母组合
  • 原文地址:https://www.cnblogs.com/juechen/p/4721900.html
Copyright © 2020-2023  润新知