POJ1149-PIGS

来源:互联网 发布:深圳网络出租屋办理 编辑:程序博客网 时间:2024/05/17 06:54

PIGS
Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 21699 Accepted: 9915

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

Source

Croatia OI 2002 Final Exam - First day


题意:一个农夫要把养殖的猪卖出去,现有m个猪圈,农夫自己没有猪圈的钥匙。现有n个客户要来买猪,每个客户手中有A把钥匙,分别表示成猪圈的编号,并且每个客户需要买一定的猪。这些客户依次过来(编号从小到大),打开他们能打开的猪圈,农夫可以选择如何将这些猪卖给每一个客户,只要头数不超过客户的需求即可。农夫在处理好每一笔交易后能够将打开的猪圈门之内的猪任意分配,并关上所有的猪圈。现在问农夫能够卖出最多的猪的数量

解题思路:建一个源点与汇点,将顾客看作节点,源点和每个猪圈的第一个顾客连边,边的权是开始时猪圈中猪的数目,顾客j紧跟在顾客i之后打开某个猪圈,则边<i,j>的权是无限大,每个顾客和汇点之间连边,边的权是顾客所希望购买的猪的数目

具体建图思路可以看https://wenku.baidu.com/view/0ad00abec77da26925c5b01c.html


#include <iostream>  #include <cstdio>  #include <cstring>  #include <string>  #include <algorithm>  #include <cmath>  #include <map>  #include <set>  #include <stack>  #include <queue>  #include <vector>  #include <bitset>    using namespace std;    #define LL long long  const int INF = 0x3f3f3f3f;  #define MAXN 500      struct node  {      int u, v, next, cap;  } edge[MAXN*MAXN];int nt[MAXN], s[MAXN], d[MAXN], a[MAXN*2+10],vis[MAXN*2+10],mp[MAXN][MAXN];  int cnt;    void init()  {      cnt = 0;      memset(s, -1, sizeof(s));  }    void add(int u, int v, int c)  {      edge[cnt].u = u;      edge[cnt].v = v;      edge[cnt].cap = c;      edge[cnt].next = s[u];      s[u] = cnt++;      edge[cnt].u = v;      edge[cnt].v = u;      edge[cnt].cap = 0;      edge[cnt].next = s[v];      s[v] = cnt++;  }    bool BFS(int ss, int ee)  {      memset(d, 0, sizeof d);      d[ss] = 1;      queue<int>q;      q.push(ss);      while (!q.empty())      {          int pre = q.front();          q.pop();          for (int i = s[pre]; ~i; i = edge[i].next)          {              int v = edge[i].v;              if (edge[i].cap > 0 && !d[v])              {                  d[v] = d[pre] + 1;                  q.push(v);              }          }      }      return d[ee];  }    int DFS(int x, int exp, int ee)  {      if (x == ee||!exp) return exp;      int temp,flow=0;      for (int i = nt[x]; ~i ; i = edge[i].next, nt[x] = i)      {          int v = edge[i].v;          if (d[v] == d[x] + 1&&(temp = (DFS(v, min(exp, edge[i].cap), ee))) > 0)          {              edge[i].cap -= temp;              edge[i ^ 1].cap += temp;              flow += temp;              exp -= temp;              if (!exp) break;          }      }      if (!flow) d[x] = 0;      return flow;  }    int Dinic_flow(int ss, int ee)  {      int ans = 0;      while (BFS(ss, ee))      {          for (int i = 0; i <= ee; i++) nt[i] = s[i];          ans+= DFS(ss, INF, ee);      }      return ans;  }    int main()  {      int n, m;      while (~scanf("%d %d", &m, &n))      {          init();  for (int i = 1; i <= m; i++) scanf("%d", &a[i]);int k,x;memset(vis, 0, sizeof vis);memset(mp, 0, sizeof mp);for (int i = 1; i <= n; i++){scanf("%d", &k);for (int j = 1; j <= k; j++){scanf("%d", &x);if (vis[x]) mp[vis[x]][i] = INF;else mp[0][i] += a[x], vis[x] = i;}scanf("%d", &x);mp[i][n + 1] = x;}for (int i = 0; i <= n + 1; i++)for (int j = 0; j <= n + 1; j++)if (mp[i][j]) add(i, j, mp[i][j]);printf("%d\n", Dinic_flow(0,n+1));      }      return 0;  } 

原创粉丝点击