POJ 1149 PIGS

PIGS

 

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

#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f,MAXN=1e3+5;
int mp[MAXN][MAXN],num[MAXN],p[MAXN],pre[MAXN],a[MAXN],m,n;
struct Edge
{
    int from,to,cap,flow;
    Edge(){}
    Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){};
};
vector<int>G[1005];
vector<Edge>edges;
void init()
{
    for(int i=0;i<n;i++)
    G[i].clear();
    edges.clear();
}
void addedge(int from,int to,int cap)
{
    edges.push_back(Edge(from,to,cap,0));
    edges.push_back(Edge(to,from,0,0));
    int m=edges.size();
    G[to].push_back(m-1);
    G[from].push_back(m-2);
}
int maxflow(int s,int t)
{
    int flow=0;
    while(1)
    {
        memset(a,0,sizeof(a));
        queue<int>q;
        q.push(s);
        a[s]=INF;
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            for(int i=0;i<G[x].size();i++)
            {
                Edge& e=edges[G[x][i]];
                if(!a[e.to]&&e.cap>e.flow)
                {
                    p[e.to]=G[x][i];
                    a[e.to]=min(a[x],e.cap-e.flow);
                    q.push(e.to);
                }
            }
            if(a[t])break;
        }
        if(!a[t])break;
        for(int u=t;u!=s;u=edges[p[u]].from)
        {
            edges[p[u]].flow+=a[t];
            edges[p[u]^1].flow-=a[t];
        }
        flow+=a[t];
    }
    return flow;
}
int main()
{
    int m,n;
    scanf("%d%d",&m,&n);
    for(int i=1;i<=m;i++)scanf("%d",&num[i]);
    for(int i=1;i<=n;i++)
    {
        int cnt;
        scanf("%d",&cnt);
        while(cnt--)
        {
            int t;
            scanf("%d",&t);
            if(!pre[t])
                addedge(0,i,num[t]);
            else
                addedge(pre[t],i,INF);
            pre[t]=i;
        }
        scanf("%d",&cnt);
        addedge(i,n+1,cnt);
    }
    printf("%d
",maxflow(0,n+1));
    return 0;
}
原文地址:https://www.cnblogs.com/homura/p/6074083.html