poj1149 pigs 網絡流

来源:互联网 发布:有什么好的淘宝会员名 编辑:程序博客网 时间:2024/06/18 11:31
PIGS
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 17680 Accepted: 8015

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

Sample Output

7



題意:略;

以顾客为点,加一个源点和汇点,源点到顾客的权为他能去的猪槽的猪数量总和,顾客到汇点的权为顾客可以买的朱数量。顾客间如果有相同的猪槽加一条INF的边。




#include <iostream>#include <stdio.h>#include <queue>#include <cmath>#include <string.h>#include <vector>#include <algorithm>#include <map>#include <queue>using namespace std;#define LL                                      long long#define scan(a)                             scanf("%d",&a)#define maxn                                1111#define REP(i,a,b)                          for(int i=a;i<b;++i)#define mset(a,b)                           memset(a,b,sizeof a)const LL mod = 1000000000;const int MAXN = 111;//点数的最大值const int MAXM = 11100;//边数的最大值const int INF = 0x3f3f3f3f;int pigs[1111];vector<int> pigRoom[1111];struct Edge{    int to,next,cap,flow;}edge[MAXM];//注意是MAXMint tol;int head[MAXN];int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];void init(){    tol = 0;    memset(head,-1,sizeof(head));}//加边,单向图三个参数,双向图四个参数void addedge(int u,int v,int w,int rw=0){    edge[tol].to =v;edge[tol].cap = w;edge[tol].next = head[u];    edge[tol].flow= 0;head[u] = tol++;    edge[tol].to =u;edge[tol].cap = rw;edge[tol].next = head[v];    edge[tol].flow= 0;head[v]=tol++;}//输入参数:起点、终点、点的总数//点的编号没有影响,只要输入点的总数int sap(int start,int end,int N){    memset(gap,0,sizeof(gap));    memset(dep,0,sizeof(dep));    memcpy(cur,head,sizeof(head));    int u = start;    pre[u] = -1;    gap[0] = N;    int ans = 0;    while(dep[start] < N)    {        if(u == end)        {            int Min = INF;            for(int i = pre[u];i != -1; i = pre[edge[i^1].to])                if(Min > edge[i].cap - edge[i].flow)                    Min = edge[i].cap - edge[i].flow;            for(int i = pre[u];i != -1; i = pre[edge[i^1].to])            {                edge[i].flow += Min;                edge[i^1].flow -= Min;            }            u = start;            ans += Min;            continue;        }        bool flag = false;        int v;        for(int i = cur[u]; i != -1;i = edge[i].next)        {            v = edge[i].to;            if(edge[i].cap - edge[i].flow && dep[v]+1 == dep[u])            {                flag = true;                cur[u] = pre[v] = i;                break;            }        }        if(flag)        {            u = v;            continue;        }    int Min = N;    for(int i = head[u]; i != -1;i = edge[i].next)        if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)        {            Min = dep[edge[i].to];            cur[u] = i;        }        gap[dep[u]]--;        if(!gap[dep[u]])return ans;        dep[u] = Min+1;        gap[dep[u]]++;        if(u != start) u = edge[pre[u]^1].to;    }    return ans;}int main(){    int s=0;    int n,m;    while(cin>>m>>n)    {        //mset(minf,0);        int e=n+1;        init();        REP(i,1,m+1)  scan(pigs[i]);        REP(i,1,n+1)        {            int A,sump=0,B;            scan(A);            REP(j,0,A)            {                int room;                scan(room);                if(pigRoom[room].size()==0)                    sump+=pigs[room];                pigRoom[room].push_back(i);            }            scan(B);            addedge(s,i,sump);            addedge(i,e,B);        }        REP(i,1,m+1)        {            int sz=pigRoom[i].size();            for(int j=0;j<sz-1;++j)            {                for(int k=j+1;k<sz;++k)                {                    addedge(pigRoom[i][j],pigRoom[i][k],INF);                }            }        }        printf("%d\n",sap(s,e,n+2));    }}




0 0
原创粉丝点击