poj 1149 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
其实网络流的题目最主要的就是构图,只要图构好了,什么都好说,这个题一开始我就想到是二分图,总是想把猪圈给放在图里,可是怎么都搞不出来,现在想想自己真是水啊
由于猪圈打开后要关闭,所以这样构图
对于第一个打开猪圈的人,就从S连一条边到他,容量为这个猪圈的猪的数目,若不是第一个打开的,就从上一个打开的连一条边到他,容量为inf,再从每个人连一条边到T,容量为他要买的猪的个数,这样跑一遍最大流就可以了
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<cmath>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define  inf 0x0f0f0f0f

using namespace std;
bool visited[1000+10];
int p[1000+10];
struct Edge
{
    int from,to,cap,flow;
};

struct DINIC{
    static const int maxn=2500+10;
    int n,m,s,t;
    vector<Edge>edges;
    vector<int>G[maxn];
    int d[maxn],cur[maxn];
    bool vis[maxn];

    void AddEdge(int from,int to,int cap)
    {
        Edge temp;
        temp.cap=cap; temp.flow=0; temp.from=from; temp.to=to;
        edges.push_back(temp);
        temp.cap=0; temp.flow=0; temp.from=to; temp.to=from;
        edges.push_back(temp);
        m=edges.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }

    bool BFS()
    {
        memset(vis,0,sizeof(vis));
        queue<int>Q;
        Q.push(s);
        d[s]=0;
        vis[s]=1;
        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 (!vis[e.to] && e.cap>e.flow)
                {
                    vis[e.to]=1;
                    d[e.to]=d[x]+1;
                    Q.push(e.to);
                }
            }
        }
        return vis[t];
    }

    int DFS(int x,int a)
    {
        if (x==t || a==0) return a;
        int flow=0,f;
        for (int& i=cur[x];i<G[x].size();i++)
        {
            Edge& e=edges[G[x][i]];
            if (d[x]+1==d[e.to] && (f=DFS(e.to,min(a,e.cap-e.flow)))>0)
            {
                e.flow+=f;
                edges[G[x][i]^1].flow-=f;
                flow+=f;
                a-=f;
                if (a==0) break;
            }
        }
        return flow;
    }

    int Dinic()
    {
        int flow=0;
        while (BFS())
        {
            memset(cur,0,sizeof(cur));
            flow+=DFS(s,inf);
        }
        return flow;
    }

    void init()
    {
        for (int i=0;i<=maxn;i++) G[i].clear();
        edges.clear();
    }
};

DINIC pig;

int main()
{
    //freopen("in.txt","r",stdin);
    int N,M,X,num;
    while(scanf("%d%d",&N,&M)!=EOF)
    {
        pig.n=M+2;
        pig.init();
        for (int i=1;i<=N;i++) scanf("%d",&p[i]);
        memset(visited,0,sizeof(visited));
        stack<int>S[1000+10];
        for (int i=1;i<=M;i++)
        {
            scanf("%d",&num);
            while(num--)
            {
                scanf("%d",&X);
                if (!visited[X])
                {
                    pig.AddEdge(0,i,p[X]);
                    visited[X]=true;
                    S[X].push(i);
                }
                else
                {
                    int v=S[X].top();
                    pig.AddEdge(v,i,inf);
                    S[X].push(i);
                }
            }
            scanf("%d",&X);
            pig.AddEdge(i,M+1,X);
        }
        pig.s=0;
        pig.t=M+1;
        int ans=pig.Dinic();
        printf("%d\n",ans);
    }
    return 0;
}

作者 chensunrise

posted @ 2014-06-09 18:40  Hust_BaoJia  阅读(217)  评论(0编辑  收藏  举报
努力