PIGS
Time Limit: 1000MS |
|
Memory Limit: 10000K |
Total Submissions: 18057 |
|
Accepted: 8210 |
Description
Mirko works on a pig farm the consists of M locked pig-houses and Mirko can ' t unlock any pighouse because he doesn ' t has The keys. Customers come to the farm one after another. Each of them have 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 is available to Mirko early in the mornin G So, he can make a sales-plan in order to maximize the number of pigs sold.
More precisely, the procedure was as following:the customer arrives, opens all pig-houses to which he had the key, Mirko s Ells a certain number of pigs from all the unlocked pig-houses to him, and, if Mirko wants, he can redistribute the remain ing pigs across the unlocked pig-houses.
An unlimited number of pigs can is placed in every pig-house.
Write a program, that would find the maximum number of pigs that he can sell on this day.
Input
The first line of input contains integers m and N, 1 <= m <=, 1 <= N <=, number of pighouses and Number of customers. Pig houses is numbered from 1 to M and customers is numbered from 1 to N.
The next line contains M Integeres, for each pig-house initial number of pigs. The number of pigs in pig-house are 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 on the i-th customer is written in The (i+2)-th line):
A K1 K2 ... Ka B It means that this customer have 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
Test instructions: There are M pigsty, in each pigsty there are several pigs at the beginning, the pigsty are closed at first. In turn, n customers, each customer will open the specified number of pig pens, from which to buy a number of pigs. After each customer walks, the pig in the pigsty he opens can be reassigned by the farmer and then shut down the pigsty. Ask the farmer how many pigs he can sell.
The problem: This topic has obvious network flow characteristics. This problem can have a lot of modeling methods, here I only introduce a relatively easy to understand modeling method. First, virtual out of source and sink point, and then from the source point to each customer with a capacity for the number of pigs they want to buy the side, each pigsty to the meeting point a volume for the number of pig sty initial side.
Then for each customer, because the pigsty can be opened to re-arbitrarily allocated the number of pigsty, so for these open pigsty is actually connected to each other, so we can virtual out a node out, pointing to these pigsty, and then the customer to the virtual node with an INF edge. For example, customer number 1th wants to be in 1, 2, pigsty 3rd sells pigs, you can virtual out a node a,a->1,a->2,a->3,1->a, so you can deal with the situation of China Unicom. But here's the problem, is that the open pigsty may all be bought by the next customer, so how do we ensure that the pigsty connectivity will continue to the following node? This is easy, you can open a Hash array, maintain each pigsty belongs to the Unicom block, such as hasn[1] = a,hash[2] = a.hash[3] = A, so that you can access the next time, then directly access to the previous Unicom block.
AC Code:
/* ***********************************************author:xdlovecreated time:2015 July 14 Tuesday 14:34 27 seconds file Name : A.cpp ************************************************ * * #include <stdio.h> #include <string.h># Include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <math.h> #include <stdlib.h> #include <time.h> Using namespace Std;typedef long long ll;const int MAXN = 3000;const int MAXM = 1e5 + 5;const int INF = 0x3f3f3f3f;struct node{int from,to,next; int cap;} EDGE[MAXM * 2];int tol;int head[maxn];int que[maxn];int DEP[MAXN]; DEP is the level of the point int stack[maxn];//stack to the stack, storing the current augmented path int cur[maxn];//to store the current point's subsequent void Init () {tol = 0; memset (head,-1,sizeof (Head));} void Add_edge (int u, int v, int w) {edge[tol].from = u; Edge[tol].to = v; Edge[tol].cap = W; Edge[tol].next = Head[u]; Head[u] = tol++; Edge[tol].from = v; Edge[tol].to = u; Edge[tol].cap = 0; Edge[tol].next = Head[v]; HEAD[V] = tol++;} int BFS (int start, int end) {int front, rear; Front = rear = 0; memset (DEP,-1, sizeof (DEP)); que[rear++] = start; Dep[start] = 0; while (front! = rear) {int u = que[front++]; if (front = = MAXN) Front = 0; for (int i = head[u]; i =-1; i = edge[i].next) {int v = edge[i].to; if (Edge[i].cap > 0 && dep[v] = =-1) {Dep[v] = Dep[u] + 1; que[rear++] = v; if (rear >= maxn) rear = 0; if (v = = end) return 1; }}} return 0;} int dinic (int start, int end) {int res = 0; int top; while (BFS (start, end)) {memcpy (cur, head, sizeof (head)); int u = start; top = 0; while (true) {if (U = = end) {int min = INF; int Loc; for (int i = 0; i < top; i++) if (min > Edge[stack[i]].cap) {min = Edge[stack[i]]. Cap loc = i; } for (int i = 0; i < top; i++) {edge[stack[i]].cap = min; Edge[stack[i] ^ 1].cap + = min; } res + = min; top = loc; u = edge[stack[top]].from; } for (int i = cur[u]; i =-1; cur[u] = i = edge[i].next) if (edge[i].cap! = 0 && Dep[u ] + 1 = = dep[edge[i].to]) break; if (cur[u]! =-1) {stack[top++] = Cur[u]; u = edge[cur[u]].to; } else {if (top = = 0) break; Dep[u] =-1; u = edge[stack[--top]].from; }}} return res;} int A[maxn],hash[maxn];int Main () {//fReopen ("In.txt", "R", stdin); Freopen ("OUT.txt", "w", stdout); int n,m; while (~SCANF ("%d%d", &m,&n)) {Init (); int s = 0,t = n + M + 1; int node = t; for (int i = 1; I <= m; i++) {scanf ("%d", &a[i]); Hash[i] = i + N; Add_edge (i + n,t,a[i]); } for (int i = 1; I <= n; i++) {int x,v; scanf ("%d", &x); node++; while (x--) {scanf ("%d", &v); Add_edge (Node,hash[v],inf); HASH[V] = node; } scanf ("%d", &x); Add_edge (S,I,X); Add_edge (I,node,inf); } printf ("%d\n", Dinic (s,t)); } return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
1149-pigs (Network flow modeling, pinch point)