POJ 1149 PIGS //MAXFLOW

来源:互联网 发布:海量数据云存储方案 编辑:程序博客网 时间:2024/05/17 01:57

PIGS
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 7773 Accepted: 3367

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 arives, 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 33 1 102 1 2 22 1 3 31 2 6

Sample Output

7

Source

Croatia OI 2002 Final Exam - First day

 

 

1)每个顾客分别用一个节点来表示。
2)对于每个猪圈的第一个顾客,从源点向他连一条边,容量就是该猪圈里的猪的初始数量。如果从源点到一名顾客有多条边,则可以把它们合并成一条,容量相加。
3)对于每个猪圈,假设有 n 个顾客打开过它,则对所有整数 i ∈ [1, n),从该猪圈的第 i 个顾客向第 i + 1 个顾客连一条边,容量为 +∞。
4)从各个顾客到汇点各有一条边,容量是各个顾客能买的数量上限。

 

#include<stdio.h>

#include<string.h>

#include<algorithm>

using namespace std;

const int inf=100000000;

 

int n,m,flow[110][110],dist[110],gap[110];//注意范围

int find_path(int p, int limit = 0x3f3f3f3f)

{

    if (p == n - 1) return limit;

    for (int i = 0; i < n; ++i)

    {

        if (dist[p] == dist[i] + 1 && flow[p][i] > 0)

        {

            int t = find_path(i, min(limit, flow[p][i]));

            if (t < 0) return t;

            if (t > 0)

            {

                flow[p][i] -= t;

                flow[i][p] += t;

                return t;

            }

        }

    }

    int label = n;

    for (int i = 0; i < n; ++i) if (flow[p][i] > 0)  label = min(label, dist[i] + 1);

    if (--gap[dist[p]] == 0 || dist[0] >= n) return -1;

    ++gap[dist[p] = label];

    return 0;

}

int iSAP()

{

    gap[0] = n;

    int maxflow = 0,t = 0;

    while ((t = find_path(0)) >= 0)  maxflow += t;

    return maxflow;

}

int ph[1001];

bool vis[1001];

int main()

{

    while(scanf("%d%d",&m,&n)!=EOF)

    {

        memset(flow,0,sizeof(flow));

        memset(gap,0,sizeof(gap));

        memset(dist,0,sizeof(dist));//注意初始化

        memset(vis,false,sizeof(vis));

        for(int i=1;i<=m;i++) scanf("%d",&ph[i]);

        int k,t,a;

        for(int i=1;i<=n;i++)

        {

            scanf("%d",&k);

            for(int j=1;j<=k;j++)

            {

                scanf("%d",&a);

                if(!vis[a])

                {

                    flow[0][i]+=ph[a];

                    vis[a]=true;

                    ph[a]=i;

                }

                else

                {

                    flow[ph[a]][i]=inf;

                    ph[a]=i;

                }

            }

            scanf("%d",&t);

            flow[i][n+1]=t;

        }

        n=n+2;

        printf("%d/n",iSAP());

    }

    return 0;

}

原创粉丝点击