POJ 1149 PIGS
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
Sample Output
Source |
[Submit] [Go Back] [Status] [Discuss]
网络流——流量传递类型。
四月份的时候曾经写过一遍,但是已然忘光了,所以只得重新来过。
错误的建图方法
看到题之后有个简单的建图想法,就是设立M*N个猪圈点,以及N个商人点,如下建图:
源点向第一排M个猪圈点连容量为初始猪数目的边,代表一开始猪圈中最多存在的猪。
每排M个猪圈点中,A个能被打开的猪圈点向商人点连容量为无穷的边,代表可以被打开。
每排的商人点向汇点连容量为商人购买数目B的边,表示这个人的最大购买限度。
每排的商人点向下一排的A个点(这A个点还是本排商人能打开的猪圈)连无穷边,代表猪可以自由转移。
当然,因为猪也可以待在猪圈里不动,所以每排的各个猪圈向下一排的该猪圈连无穷边。
这样跑最大流,显然可以得到最优解,但是点的数量是O(N*M)的,而边的数量是……(懒得想了),果不其然地TLE了。
- #include <cstdio>
- #include <cstring>
- inline int get_c(void)
- {
- static const int siz = ;
- static char buf[siz];
- static char *head = buf + siz;
- static char *tail = buf + siz;
- if (head == tail)
- fread(head = buf, , siz, stdin);
- return *head++;
- }
- inline int get_i(void)
- {
- register int ret = ;
- register int neg = false;
- register int bit = get_c();
- for (; bit < ; bit = get_c())
- if (bit == '-')neg ^= true;
- for (; bit > ; bit = get_c())
- ret = ret * + bit - ;
- return neg ? -ret : ret;
- }
- template <class T>
- inline T min(T a, T b)
- {
- return a < b ? a : b;
- }
- const int inf = 2e9;
- const int maxn = ;
- int n, m;
- int s, t;
- int edges;
- int hd[maxn];
- int to[maxn];
- int nt[maxn];
- int fl[maxn];
- inline void add(int u, int v, int f)
- { //printf("add %d %d %d\n", u, v, f);
- nt[edges] = hd[u]; to[edges] = v; fl[edges] = f; hd[u] = edges++;
- nt[edges] = hd[v]; to[edges] = u; fl[edges] = ; hd[v] = edges++;
- }
- int dep[maxn];
- inline bool bfs(void)
- {
- static int que[maxn];
- static int head, tail;
- memset(dep, , sizeof(dep));
- head = , tail = ;
- que[tail++] = s;
- dep[s] = ;
- while (head != tail)
- {
- int u = que[head++], v;
- for (int i = hd[u]; ~i; i = nt[i])
- if (!dep[v = to[i]] && fl[i])
- {
- dep[v] = dep[u] + ;
- que[tail++] = v;
- }
- }
- return dep[t] != ;
- }
- int dfs(int u, int f)
- {
- if (u == t || !f)
- return f;
- int used = , flow, v;
- for (int i = hd[u]; ~i; i = nt[i])
- if (dep[v = to[i]] == dep[u] + && fl[i])
- {
- flow = dfs(v, min(f - used, fl[i]));
- used += flow;
- fl[i] -= flow;
- fl[i^] += flow;
- if (used == f)
- return f;
- }
- if (!used)
- dep[u] = ;
- return used;
- }
- inline int maxFlow(void)
- {
- int maxFlow = , newFlow;
- while (bfs())
- while (newFlow = dfs(s, inf))
- maxFlow += newFlow;
- return maxFlow;
- }
- signed main(void)
- {
- n = get_i();
- m = get_i();
- s = , t = (n + ) * m + ;
- memset(hd, -, sizeof(hd));
- for (int i = ; i <= n; ++i)
- {
- int pigs = get_i();
- add(s, i, pigs);
- }
- for (int i = ; i < m; ++i)
- for (int j = ; j <= n; ++j)
- add((n + )*(i - ) + j, (n + )*i + j, inf);
- for (int i = ; i <= m; ++i)
- {
- int k = get_i();
- for (int j = ; j <= k; ++j)
- {
- int p = get_i();
- add((n + )*(i - ) + p, (n + )*i, inf);
- add((n + )*i, (n + )*i + p, inf);
- }
- add((n + )*i, t, get_i());
- }
- printf("%d\n", maxFlow());
- }
正确的建图方法
设置一个源点,向M个猪圈点连初始数目的边,代表一开始的猪的数目。
然后想办法简化猪圈之间的转移,着重商人能得到的猪的来源,考虑直接在商人之间进行转移。
易知,如果商人X和商人Y,有X比Y先来,且X和Y有公共的猪圈的钥匙,那么Y能享受X能到达的所有猪圈。
用last_i表示上一个可以打开i猪圈的点,初始last_i=i猪圈初始点。
一个商人,如果有猪圈k的钥匙,那么last_k的所有流量都可以向这个商人转移,所有从last_k向商人连边,同时把last_k设为该商人。
商人点向汇点连最大购买数量的边。
跑最大流即可,点数O(N+M),边数O(N+M),小菜一碟了。
- #include <cstdio>
- #include <cstring>
- inline int get_c(void)
- {
- static const int siz = ;
- static char buf[siz];
- static char *head = buf + siz;
- static char *tail = buf + siz;
- if (head == tail)
- fread(head = buf, , siz, stdin);
- return *head++;
- }
- inline int get_i(void)
- {
- register int ret = ;
- register int neg = false;
- register int bit = get_c();
- for (; bit < ; bit = get_c())
- if (bit == '-')neg ^= true;
- for (; bit > ; bit = get_c())
- ret = ret * + bit - ;
- return neg ? -ret : ret;
- }
- template <class T>
- inline T min(T a, T b)
- {
- return a < b ? a : b;
- }
- const int inf = 2e9;
- const int maxn = ;
- int n, m;
- int s, t;
- int edges;
- int hd[maxn];
- int to[maxn];
- int nt[maxn];
- int fl[maxn];
- inline void add(int u, int v, int f)
- { //printf("add %d %d %d\n", u, v, f);
- nt[edges] = hd[u]; to[edges] = v; fl[edges] = f; hd[u] = edges++;
- nt[edges] = hd[v]; to[edges] = u; fl[edges] = ; hd[v] = edges++;
- }
- int dep[maxn];
- inline bool bfs(void)
- {
- static int que[maxn];
- static int head, tail;
- memset(dep, , sizeof(dep));
- head = , tail = ;
- que[tail++] = s;
- dep[s] = ;
- while (head != tail)
- {
- int u = que[head++], v;
- for (int i = hd[u]; ~i; i = nt[i])
- if (!dep[v = to[i]] && fl[i])
- {
- dep[v] = dep[u] + ;
- que[tail++] = v;
- }
- }
- return dep[t] != ;
- }
- int dfs(int u, int f)
- {
- if (u == t || !f)
- return f;
- int used = , flow, v;
- for (int i = hd[u]; ~i; i = nt[i])
- if (dep[v = to[i]] == dep[u] + && fl[i])
- {
- flow = dfs(v, min(f - used, fl[i]));
- used += flow;
- fl[i] -= flow;
- fl[i^] += flow;
- if (used == f)
- return f;
- }
- if (!used)
- dep[u] = ;
- return used;
- }
- inline int maxFlow(void)
- {
- int maxFlow = , newFlow;
- while (bfs())
- while (newFlow = dfs(s, inf))
- maxFlow += newFlow;
- return maxFlow;
- }
- int last[maxn];
- signed main(void)
- {
- n = get_i();
- m = get_i();
- s = , t = n + m + ;
- memset(hd, -, sizeof(hd));
- for (int i = ; i <= n; ++i)
- add(s, i, get_i()), last[i] = i;
- for (int i = ; i <= m; ++i)
- {
- for (int j = get_i(), k; j--; )
- k = get_i(), add(last[k], n + i, inf), last[k] = n + i;
- add(n + i, t, get_i());
- }
- printf("%d\n", maxFlow());
- }
@Author: YouSiki
POJ 1149 PIGS的更多相关文章
- poj 1149 Pigs 网络流-最大流 建图的题目(明天更新)-已更新
题目大意:是有M个猪圈,N个顾客,顾客要买猪,神奇的是顾客有一些猪圈的钥匙而主人MIRKO却没有钥匙,多么神奇?顾客可以在打开的猪圈购买任意数量的猪,只要猪圈里有足够数量的猪.而且当顾客打开猪圈后mi ...
- POJ 1149 PIGS(Dinic最大流)
PIGS Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 20738 Accepted: 9481 Description ...
- poj 1149 PIGS【最大流经典建图】
PIGS Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 18727 Accepted: 8508 Description ...
- 网络流(最大流):POJ 1149 PIGS
PIGS Time Limit: 1000ms Memory Limit: 10000KB This problem will be judged on PKU. 64-bit integer(整数) ...
- POJ 1149 - PIGS - [最大流构图]
Time Limit: 1000MS Memory Limit: 10000K Description Mirko works on a pig farm that consists of M loc ...
- POJ 1149 PIGS(最大流)
Description Mirko works on a pig farm that consists of M locked pig-houses and Mirko can't unlock an ...
- POJ 1149 PIGS (AC这道题很不容易啊)网络流
PIGS Description Mirko works on a pig farm that consists of M locked pig-houses and Mirko can't unlo ...
- POJ 1149 PIGS 【网络流】
题意: m n //有m个猪圈,n个人卖猪. a1...am //编号为i的猪圈里有ai头猪. b1 c1...cb1 d1 //第i个人有bi把钥匙,分别是ci猪圈的,其它猪圈里的猪都 ...
- POJ 1149 PIGS ★(经典网络流构图)
[题意] 有M个猪圈,每个猪圈里初始时有若干头猪.一开始所有猪圈都是关闭的.依 次来了N个顾客,每个顾客分别会打开指定的几个猪圈,从中买若干头猪.每 个顾客分别都有他能够买的数量的上限.每个顾客走后, ...
随机推荐
- atitit.日期,星期,时候的显示方法ISO 8601标准
atitit.日期,星期,时候的显示方法ISO 8601标准 1. ISO 86011 2. DAte日期的显示1 2.1. Normal1 2.2. 顺序日期表示法(可以将一年内的天数直接表示)1 ...
- echarts学习总结
ECharts学习总结使用步骤1 引入ECharts <script src="echarts.min.js"></script>2 绘制一个简单的图表 为 ...
- 安装pip
1. 安装pip. 我们同样需要在Python的官网上去下载,下载地址是: https://pypi.python.org/pypi/pip#downloads 2. 解压. 解压pip-9.0.1. ...
- CartO
Carto documentation The following is a list of properties provided in CartoCSS that you can apply to ...
- iOS系统分析(二)Mach-O二进制文件解析
➠更多技术干货请戳:听云博客 0x01 Mach-O格式简单介绍 Mach-O文件格式是 OS X 与 iOS 系统上的可执行文件格式,类似于windows的 PE 文件 与 Linux(其他 Un ...
- grunt-笔记
package.json: { "name": "grunt-uglify", "version": "1.0.0", ...
- 感受C# 的魅力,将一坨代码写成一行
摘自MSDN :https://msdn.microsoft.com/zh-cn/library/bb549151(v=vs.100).aspx 1.平时定义一个委托 using System; // ...
- ASP.NET MVC 身份认证
身份认证的好处就是, 如果这个页面没有登录, 刷新后会自动跳到登录页要求登录,保证了应用程序的安全.而Forms 身份认证是web下最常用的,如何配置呢?见下(基于mvc 4) 1.在webconfi ...
- ORA-00600 3020 ORA-10567案例
PlateSpin克隆复制出的Oracle数据库服务器,往往启动数据库实例都会遇到一些杂七杂八的问题.今天测试DR环境时又遇到了一个特殊场景,在此之前,我已经遇到了下面两起案例: ORA-00600: ...
- JSON-RPC 2.0 规范中文文档
链接地址如下 http://wiki.geekdream.com/Specification/json-rpc_2.0.html