poj 1149 PIGS

PIGS
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 14358 Accepted: 6390

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
Sap+gap+cur
 
# include < iostream >
# include < cstdio >
# include < algorithm >
//#include <cstring>
//#include <cmath>
# include < queue >
# include < set >
# define INF 2000000000
# define maxn 1050
# define min(a, b) a < b ? a : b
using namespace std;
 
int pre[maxn];
int dis[maxn];
int flow;
int front[maxn];
int cur[maxn];
int gap[maxn];
int used[maxn];
int index;
int n, m;
 
struct Edge{
     int v;
     int w;
     int next;
}e[maxn * maxn];
 
void init(){
    index = 0 ;
    memset( pre, - 1 , sizeof (pre) );
    memset( used, 0 , sizeof (used) );
}
 
void insert( int u, int v, int w ){
    e[index].v = v;
    e[index].w = w;
    e[index].next = pre[u];
    pre[u] = index ++ ;
 
    e[index].v = u;
    e[index].w = 0 ;
    e[index].next = pre[v];
    pre[v] = index ++ ;
}
 
int maxflow_sap( int s, int t ){
    memset( dis, 0 , sizeof (dis) );
    memset( gap, 0 , sizeof (gap) );
     for ( int i = 0 ; i < = n; i ++ ){
        cur[i] = pre[i];
    }
     int u = s, maxflow = 0 ;
    flow = INF;
     //gap[0] = t;
    front[s] = - 1 ;
 
     while ( dis[s] < t + 1 ){
         int i;
         for ( i = cur[u]; i != - 1 ; i = e[i].next ){
             if ( dis[u] == dis[e[i].v] + 1 && e[i].w > 0 ){
                 break ;
            }
        }
        cur[u] = i;
         if ( cur[u] != - 1 ){
            flow = min( flow, e[i].w );
            front[e[i].v] = u;
            u = e[i].v;
             if ( u == t ){
                maxflow += flow;
                 for ( i = front[t]; i != - 1 ; i = front[i] ){
                    e[cur[i]].w -= flow;
                    e[cur[i] ^ 1 ].w += flow;
                }
                u = s;
                flow = INF;
            }
        }
         else {
             int mindis = t + 1 ;
             for ( i = pre[u]; i != - 1 ; i = e[i].next ){
                 if ( e[i].w > 0 && mindis > dis[e[i].v] + 1 ){
                    mindis = dis[e[i].v] + 1 ;
                    cur[u] = i;
                }
            }
            gap[dis[u]] -- ;
             if ( ! gap[dis[u]] ){
                 break ;
            }
            dis[u] = mindis;
            gap[mindis] ++ ;
             if ( u != s ){
                u = front[u];
            }
        }
    }
     return maxflow;
}
 
 
 
int main(){
     //freopen("in.txt", "r", stdin);
     //freopen("o.txt", "w", stdout);
     int t = 0 ;
     while ( ~ scanf( "%d%d" , & m, & n) ){
        init();
         int i;
         int node[maxn];
         for ( i = 1 ; i < = m; i ++ ){
             int w;
            scanf( "%d" , & node[i]);
        }
         int k, a, b, w;
         for ( i = 1 ; i < = n; i ++ ){
            scanf( "%d" , & k);
             /*if ( k ){
                scanf("%d", &a);
                if ( !used[a] ){
                    insert();
                }
            }*/

             int cnt = 0 ;
             for ( int j = 0 ; j < k; j ++ ){
                scanf( "%d" , & a);
                 if ( ! used[a] ){
                    cnt += node[a];
                }
                 else {
                    insert( used[a], i, INF );
                }
                used[a] = i;
            }
            insert( 0 , i, cnt );
            scanf( "%d" , & w);
            insert( i, n + 1 , w );
        }
         //printf("%d : ", ++t);
        printf( "%d\n" , maxflow_sap( 0 , n + 1 ) );
    }
     return 0 ;   
}
/*
2 5
2 100
2 1 2 1
1 2 2
1 2 2
1 2 2
1 2 2
 
9 5
11 4 10 10 11 3 12 3 3
1 6 6
5 7 6 9 2 1 5
5 4 3 6 1 5 2
1 6 8
2 4 9 3
 
*/
 




posted @ 2013-08-25 22:53  /bin  阅读(152)  评论(0编辑  收藏  举报