[网络流]poj1149 PIGS
来源:互联网 发布:怎么积累淘宝关注人数 编辑:程序博客网 时间:2024/05/19 00:14
题意:
一个农场有M个猪圈,每个猪圈里有很多猪,现在有N个顾客,每个顾客可以拿到一些猪圈的钥匙来买猪,买完之后会关上门,顾客是严格按照顺序来的,不会出现顾客A和顾客B同时在农场的情况。顾客打开门之后,这个猪圈里的猪可以任意换到其他的打开着的猪圈中,求最多能卖多少只猪。
思路:
这样的网络流题目,必然要构图。
从源点开始,向每个猪圈的第一个顾客连一条边,容量为这个猪圈的猪的数量。接着后面来的顾客由上一个到这个猪圈的顾客连接上,容量为∞
每一个顾客都连接一条弧到汇点,容量为他需要的猪的数量。
可以这样解释:
从源点开始,连接到每一个猪圈,容量为这个猪圈的猪的数量,再连接到第一个顾客,这时候,第一个顾客连两条边,一条连到汇点,另一条连到新开的一个节点,这个节点连接的就是后来来的顾客,这样重复,将部分路径压缩,也就是因为猪圈只会连到第一个顾客,就直接从源点连到第一个顾客。第一个顾客连完汇点之后,再连后来的顾客,这时候省略了中间作为中介的节点,而且查询起来也很快。
最后建好图,做一次最大流即可得到答案。
如图,这是原题根据样例构成的图:
总结:
网络流的题目,通常会出现很难连边或是很占用空间的情况,所以要想办法简化网络,从而达到更好的效果。
代码:
#include <queue>#include <vector>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int MAXN = 1000 + 10, INF = 0x3f3f3f3f, s = 0, t = 101;struct Edge { int from, to, cap, flow; Edge(int u, int v, int c, int f) : from(u), to(v), cap(c), flow(f) {}};struct EdmondsKarp { int n, m; vector < Edge > edges; vector < int > G[MAXN]; int a[MAXN]; int p[MAXN]; void AddEdge(int from, int to, int cap) { edges.push_back(Edge(from, to, cap, 0)); edges.push_back(Edge(to, from, 0, 0)); m = edges.size(); G[from].push_back(m - 2); G[to].push_back(m - 1); } int Maxflow(int s, int t) { int flow = 0; for(;;) { memset(a, 0, sizeof a); queue < int > Q; Q.push(s); a[s] = INF; while(!Q.empty()) { int x = Q.front(); Q.pop(); for(int i = 0; i < G[x].size(); ++i) { Edge& e = edges[G[x][i]]; if(!a[e.to] && e.cap > e.flow) { p[e.to] = G[x][i]; a[e.to] = min(a[x], e.cap - e.flow); Q.push(e.to); } } if(a[t]) { break; } } if(!a[t]) { break; } for(int u = t; u != s; u = edges[p[u]].from) { edges[p[u]].flow += a[t]; edges[p[u] ^ 1].flow -= a[t]; } flow += a[t]; } return flow; }} ek;int main(void) {int m, n;cin >> m >> n;int N_pig[MAXN];int last_cus[MAXN];memset(last_cus, 0, sizeof last_cus);for(int i = 1; i <= m; ++i) {cin >> N_pig[i];}for(int i = 1; i <= n; ++i) {int N;cin >> N;for(int j = 0; j < N; ++j) {int can_visiting;cin >> can_visiting;if(last_cus[can_visiting] == 0) {ek.AddEdge(s, i, N_pig[can_visiting]);} else {ek.AddEdge(last_cus[can_visiting], i, INF);}last_cus[can_visiting] = i;}int wanted;cin >> wanted;ek.AddEdge(i, t, wanted);}cout << ek.Maxflow(s, t); return 0;}
0 0
- poj1149 PIGS(网络流)
- [网络流]poj1149 PIGS
- Poj1149 PIGS (经典网络流)
- POJ1149 PIGS 网络最大流
- POJ1149——PIGS(网络流)
- poj1149 PIGS 网络最大流Dinic
- POJ1149 PIGS(最大流)
- poj1149 最大流 PIGS
- POJ1149 PIGS 【最大流】
- POJ1149:PIGS 最大流
- poj1149 PIGS --- 最大流EK
- POJ1149 PIGS (最大流)
- POJ1149 PIGS(最大流)
- POJ1149:PIGS(最大流)
- poj1149 PIGS
- poj1149(pigs)
- POJ1149:PIGS
- poj1149 - PIGS
- 反距离加权插值方法——C#实现
- lucene入门简介
- 数据结构实验之数组三:快速转置(sdut_3347)
- foreach语句和continue语句
- 82. Remove Duplicates from Sorted List II
- [网络流]poj1149 PIGS
- Shiro 介绍
- 【NOIP模拟】腐败
- 回看JSP——解决提交form表单出现的乱码问题
- hdu2089 数位dp
- 程序猿的8个好习惯
- child伪类选择符入门(2)
- linux下cp复制文件或目录指令介绍
- Minimum height tree