POJ 1149 PIGS 建图,最大流

题意:

你m个猪圈以及每个猪圈里原来有多少头猪,先后给你n个人,每个人能打开某一些猪圈并且他们最多想买Ki头猪,在每一个人买完后能将打开的猪圈中的猪顺意分配在这次打开猪圈里,在下一个人来之前 已打开的猪圈会被锁上。
问最多能卖几头猪

分析:

  这个题明着想呢,肯定是要建N排点的,表示相同的猪圈的点连inf边,跑最大流的。

  建那么多点肯定是会炸的。

  在网络流中呢,如果我们做题的初步思路是最大流,那么肯定要将题目中问的直接问题抽象成水流,比如这道题,问最多的卖猪数,我们当然就要把猪的数量作为“流”,这是大家心照不宣的。

  所谓建图呢?个人认为,网络流最终要的是“限制”二字,网络流的流量和连边就是一个个限制问题,所以我们要参透题目中给的限制问题,有时并不必要把图中的每一个关系都建边。

  像这个题目中,猪圈里猪的数量是限制,每个人能打开的猪圈也是限制,买家的先后顺序也是限制,买猪的数量也是限制。所以我们只需要用这些限制构建模型,开始:

  源点到每个猪圈来买的第一个人连一条容量为该猪圈里猪的数量的边(这个满足了第一、二个限制)

  对于每个猪圈,第i个来买的人向第i+1个来买的人连一条容量为正无穷的边(这个满足了第三个限制)

  每个人向汇点连一条容量为购买数量的边(这个满足了第四个限制)

  网络流就是这样,严密合理得像一个故事一样。

  一头猪,从猪圈出来经过几人之手最终被某个人买走,完成了他的使命。一单位流量从原点,流经一些人,最终流向汇点,也完成了它的使命。这边是对网络流的感性理解。

代码:

 1 #include<algorithm>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<queue>
 6 #include<cmath>
 7 #define ms(a,x) memset(a,x,sizeof(a))
 8 using namespace std;
 9 const int N=105,M=1005,inf=1e9;
10 struct node{int y,z,nxt;}e[N*M*2];
11 int n,m,S,T,pg[M],nw[M],c=1;
12 int q[N],h[N],d[N],vis[N];
13 void add(int x,int y,int z){
14     e[++c]=(node){y,z,h[x]};h[x]=c;
15     e[++c]=(node){x,0,h[y]};h[y]=c;
16 } bool bfs(){
17     int f=0,t=0;ms(d,-1);
18     q[t++]=S;d[S]=0;
19     while(f<t){
20         int x=q[f++];
21         for(int i=h[x],y;i;i=e[i].nxt)
22         if(d[y=e[i].y]==-1&&e[i].z)
23         d[y]=d[x]+1,q[t++]=y;
24     } return (d[T]!=-1);
25 } int dfs(int x,int f){
26     if(x==T) return f;int w,tmp=0;
27     for(int i=h[x],y;i;i=e[i].nxt)
28     if(d[y=e[i].y]==d[x]+1&&e[i].z){
29         w=dfs(y,min(f-tmp,e[i].z));
30         if(!w) d[y]=-1;
31         e[i].z-=w;e[i^1].z+=w;
32         tmp+=w;if(tmp==f) return f;
33     } return tmp;
34 } int dinic(){
35     int tot=0;
36     while(bfs()) tot+=dfs(S,inf);
37     return tot;
38 } int main(){
39     scanf("%d%d",&m,&n);S=0;T=n+1;
40     for(int i=1;i<=m;i++)
41     scanf("%d",&pg[i]);
42     for(int i=1;i<=n;i++){
43         int a,b,x;scanf("%d",&a);
44         while(a--){
45             scanf("%d",&x);
46             if(!nw[x]) add(S,i,pg[x]),nw[x]=i;
47             else add(nw[x],i,inf),nw[x]=i;
48         } scanf("%d",&b);add(i,T,b);
49     } printf("%d",dinic());
50     return 0;
51 }

最大流

原文地址:https://www.cnblogs.com/Alan-Luo/p/10241712.html

时间: 2024-10-12 11:13:03

POJ 1149 PIGS 建图,最大流的相关文章

POJ 1149 PIGS(Dinic最大流)

PIGS Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20738   Accepted: 9481 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 t

POJ 1149 PIGS(最大流+建图)

题目链接:http://poj.org/problem?id=1149 题意:M个猪圈,N个顾客,每个顾客有一些的猪圈的钥匙,只能购买能打开的猪圈里的猪,而且要买一定数量的猪,每个猪圈有已知数量的猪, 但是猪圈可以重新打开,将猪的个数,重新分配,但是只能将猪往当前打开状态的猪圈里赶,以达到卖出的猪的数量最多. 思路:还是4部分,源点->猪圈->猪圈->汇点 Accepted 976K 63MS C++ 能用EK水的,当然用EK水 #include <iostream> #in

POJ 1149 PIGS 最大流

第一次做网络流,看着教材里面的题解做的= = 用的是Ford,应该是最好理解的把,就是不断的找有没有从源点到汇点的增广路然后更新. 建图真是难啊,而且感觉细节要注意的地方比较多,一开始没有考虑反向弧,WA了两发,sad... #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <strin

POJ 1149 PIGS(最大流)

POJ 1149 PIGS 题目链接 题意:有n个猪圈,m个顾客,猪圈中一开始有一些猪,顾客轮流来(注意是有先后顺序的),然后每个顾客会开启一些猪圈,在开启的猪圈中最多买b只猪,之后可以任意把剩下的猪分配到开着的猪圈中,问最多能卖出几只猪 思路:这题的关键在于建模,由于顾客有先后顺序,假如后来的顾客会开启x门,前面一个顾客也会开启x门,那么前面顾客相当与可以分配给后面顾客, 所以建模的方式为,源点和每个猪圈连,容量为猪圈猪数,每个猪圈和第一个开的顾客连,如果后面有顾客会开这个猪圈,则和之前的顾客

POJ 1149 PIGS 迈克卖猪问题 网络流构图+三种AC方法

题目链接:POJ 1149 PIGS PIGS Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16533   Accepted: 7403 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 key

poj 1149 PIGS(网络流dinic)

PIGS Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16054   Accepted: 7185 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 t

【bzoj4276】[ONTAK2015]Bajtman i Okr?g?y Robin 线段树优化建图+费用流

题目描述 有n个强盗,其中第i个强盗会在[a[i],a[i]+1],[a[i]+1,a[i]+2],...,[b[i]-1,b[i]]这么多段长度为1时间中选出一个时间进行抢劫,并计划抢走c[i]元.作为保安,你在每一段长度为1的时间内最多只能制止一个强盗,那么你最多可以挽回多少损失呢? 输入 第一行包含一个正整数n(1<=n<=5000),表示强盗的个数. 接下来n行,每行包含三个正整数a[i],b[i],c[i](1<=a[i]<b[i]<=5000,1<=c[i]

HDU 4292 Food(建图+最大流)

使用 PVRTC 压缩格式创建纹理(Creating textures in the PVRTC compression format) 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS.Android.Html5.Arduino.pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 有关该篇

POJ 1149 PIGS (网络最大流 Dinic 建对图你就赢了)

PIGS Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17598   Accepted: 7977 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 t