poj 1149 Pigs 网络流-最大流 建图的题目(明天更新)-已更新
题目大意:是有M个猪圈,N个顾客,顾客要买猪,神奇的是顾客有一些猪圈的钥匙而主人MIRKO却没有钥匙,多么神奇?顾客可以在打开的猪圈购买任意数量的猪,只要猪圈里有足够数量的猪。而且当顾客打开猪圈后mirko就可以在打开的猪圈之间任意调整猪的数量,(顾客走了之后猪圈要关闭)。问mirko怎样做能使顾客买到最多的猪
思路如下:(也是查的,具体原理和原因明天更新)
1.取超级源点和超级汇点;
2.当猪圈被第一次打开时,在源点与当前顾客之间连接一条边,容量为该猪圈的猪的头数;
3.当某个猪圈 不是被第一次打开时,在上一个打开该猪圈的顾客与当前打开该猪圈的顾客之间连接一条边,容量为无穷大;
4.在每个顾客与汇点之间连接一条边,容量为该顾客要买猪的头数。
构图完成后套用Edmonds-Karp算法的模版即可,当然用Dinic算法也可以解出。
【更新】/**************************************
想一下这题,其实猪圈应该是源点,顾客应该是汇点顾客,买猪就相当于从源点往汇点运东西,是吧?但是有点不对,那个边的容量是什么呢?应该是猪圈的猪的数量吗?嗯,想一下好像是的,但是还有一个数据——顾客期望购买的猪的数量这个数据放到哪里呢?这样一想我们建图肯定是有问题的,是吧?而且这样一做之后我们的图中就有很多源点和汇点了,这个问题当然很好解决,加一个超级源点,和一个超级汇点这样问题貌似解决了,我们可以把顾客的期望购买猪的数量和超级汇点建立一条边,容量为顾客期望购买的猪的数量,源点和猪圈之间也连一条边,边权为猪圈猪的数量,这样做对吗?好像是对的但是还有一个问题没有解决,顾客有多个猪圈的钥匙,买完猪后mirko可以调整猪圈猪的数量,这个特性没能在图中显示出来。其实这个特性也好解决当一些猪圈被同一个人打开后这些猪圈之间的猪就可以自由流通了,是吧?也就相当于可以任意调整猪圈内猪的数量了,于是我们可以在对于2个连续的顾客打开的猪圈之间有公共的猪圈的顾客之间连一条边,当然是要从先买猪的顾客连向后买猪的顾客,这样猪就能流通了是吧?,因为顾客打开的猪圈的猪是可以流向顾客的,然后顾客又流向另一个顾客,不就相当于先打开的猪圈的猪可以往后来的顾客打开的猪圈的猪进行流通了吗?(当然条件是他们打开过同一个猪圈)这样图就建好了。终于建完了图。看看我用第一组样例画的图吧(很挫啊)。
看看这个图总觉得有些东西很多余,看看源点到猪圈的边和猪圈到顾客的边是不是有点重复的感觉?其实这里有些边是可以合并的,看一下从猪圈2分出的2条边一个是到顾客1,一个是到顾客3的边但是顾客1到3又有一条边权为INF(无穷大的边)很明显2->3的边可以由2->1->3这2两条边替代,所以
2->3这条边其实是多余的,那么我们可以把这条边去掉,同理还有别的一些边也是可以去掉的,去掉后的图如下
很神奇吧?再仔细看一下图,是不是发现,猪圈是多余的了呢?我们可以吧猪圈1 和 2 合并因为它们都是指向顾客1的然后合并2条边,同理猪圈3也可以省略。省略后的图如下
现在再看一下我百度的建图思路:
.取超级源点和超级汇点;
2.当猪圈被第一次打开时,在源点与当前顾客之间连接一条边,容量为该猪圈的猪的头数;
3.当某个猪圈 不是被第一次打开时,在上一个打开该猪圈的顾客与当前打开该猪圈的顾客之间连接一条边,容量为无穷大;
4.在每个顾客与汇点之间连接一条边,容量为该顾客要买猪的头数。
哈哈,是不是一样一样的了,现在理解为什么要这样建图了吧?
******************************************/
我的代码如下,有详细的注释
/*********
PRO: POJ 1149
TIT: Pigs
DAT: 2013-08-13-08.09
AUT: UKean
EMA: huyocan@163.com
*********/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define INF 1e9
using namespace std;
queue<int> que;//广搜需要使用的队列
int M,N;//M是边数,N是点数
int s,t;//源点和汇点
int flow[115][115];//流量
int p[105];//广搜记录路径的父节点数组
int a[105];//路径上的最小残量
int cap[115][115];//容量网络
int zhujuan[1007];//猪圈记录猪圈里猪的个数
int tag[1007];//标记这个猪圈有没有打开,打开了上次是被谁打开的 int read()//读入建图部分
{
int m,n,ca;
if(!(cin>>m>>n)) return 0;//读入结束
M=n+1;//节点的个数
s=0,t=M;//超级源点,超级汇点
memset(cap,0,sizeof(cap));//初始化容量网络
for(int i=1;i<=m;i++)//m个猪圈
cin>>zhujuan[i];//猪圈的容量
memset(tag,0,sizeof(tag));//初始化标记
for(int i=1;i<=n;i++)
{
int num,temp;
cin>>num;//读入第i个的钥匙数量
for(int j=0;j<num;j++)
{
cin>>temp;//读入猪圈的钥匙
if(!tag[temp])//如果这个猪圈是第一次打开
{
tag[temp]=i;//记录猪圈最后一个打开的人是谁
cap[s][i]+=zhujuan[temp];//让源点和顾客连一条边,注意这个要合并边权
}
else
{
cap[tag[temp]][i]=INF;//让当前的人和最后打开temp猪圈的人连一条边
tag[temp]=i;//记录猪圈最后一个打开的人是谁
}
}
cin>>ca;//顾客期望购买的猪的数
cap[i][t]+=ca;//让顾客和汇点建立一条边
}
return 1;
} int deal()//增广路算法就不具体解释了,详细的解释可以看我关于网络流的第一篇博客
// http://blog.csdn.net/hikean/article/details/9918093
{
memset(flow,0,sizeof(flow));
int ans=0;
while(1)
{
memset(a,0,sizeof(a));
a[s]=INF;
que.push(s);
while(!que.empty())
{
int u=que.front();que.pop();
for(int v=0;v<=M;v++)
if(!a[v]&&cap[u][v]-flow[u][v]>0)
{
p[v]=u;
que.push(v);
a[v]=min(a[u],cap[u][v]-flow[u][v]);
}
}
if(a[t]==0) break;
for(int u=t;u!=s;u=p[u])
{
flow[p[u]][u]+=a[t];
flow[u][p[u]]-=a[t];
}
ans+=a[t];
}
cout<<ans<<endl;
return ans;
}
int main()
{
while(read())
deal();
return 0;
}
poj 1149 Pigs 网络流-最大流 建图的题目(明天更新)-已更新的更多相关文章
- poj 3281 Dining 网络流-最大流-建图的题
题意很简单:JOHN是一个农场主养了一些奶牛,神奇的是这些个奶牛有不同的品味,只喜欢吃某些食物,喝某些饮料,傻傻的John做了很多食物和饮料,但她不知道可以最多喂饱多少牛,(喂饱当然是有吃有喝才会饱) ...
- poj 1149 PIGS【最大流经典建图】
PIGS Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 18727 Accepted: 8508 Description ...
- POJ 1149 PIGS 【最大流】
<题目链接> 题目大意:有一个养猪场,厂长没有钥匙,这个养猪场一共M个猪圈,N个顾客,每个顾客有一些猪圈的钥匙,每个顾客需要一些猪,问你厂长最多能卖多少猪?这里有个条件是,厂长可以在一个顾 ...
- poj 1149 PIGS【最大流】
建图:s向所有猪圈的第一个顾客连流量为这个猪圈里住的数量,然后对于之后每个来这个猪圈的顾客,由他前一个顾客向他连边权为无穷的边,然后每个顾客向t连流量为这个顾客购买上限的边.然后跑最大流 #inclu ...
- 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(最大流经典构图)
题目描述:迈克在一个养猪场工作,养猪场里有M 个猪圈,每个猪圈都上了锁.由于迈克没有钥匙,所以他不能打开任何一个猪圈.要买猪的顾客一个接一个来到养猪场,每个顾客有一些猪圈的钥匙,而且他们要买一定数量的 ...
- 图论--网络流--最大流--POJ 3281 Dining (超级源汇+限流建图+拆点建图)
Description Cows are such finicky eaters. Each cow has a preference for certain foods and drinks, an ...
- POJ 1149 - PIGS - [最大流构图]
Time Limit: 1000MS Memory Limit: 10000K Description Mirko works on a pig farm that consists of M loc ...
- poj 3281 最大流+建图
很巧妙的思想 转自:http://www.cnblogs.com/kuangbin/archive/2012/08/21/2649850.html 本题能够想到用最大流做,那真的是太绝了.建模的方法很 ...
随机推荐
- Java String.contains()方法(转载)
Java String.contains()方法 Java String.contains()方法用法实例教程, 返回true,当且仅当此字符串包含指定的char值序列 描述 java.lang.St ...
- PHP、JSP、.NET各自的真正优势是什么
PHP的优势在于, 跨平台, 极易部署, 易维护, 为Web而生, 开源社区强大, 文档丰富.至于说3足鼎立, 谈不上, 全球前100万的sites中, 70%是PHP. JSP和Asp..net 也 ...
- 1500: [NOI2005]维修数列
Description Input 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一 ...
- LinkedHasMap实现原理
转载:http://blog.csdn.net/luanlouis/article/details/43017071 Map作为键值对Entry<K,V>的的容器,对其内部 键值对Entr ...
- CKplayer 新手入门超简单使用教程
网页播放器都有使用的前提(问1). ~~~~~~~分隔线~~~~~~~ 只需一步先看播放器效果(问2): 下载附件,解压内容(ckplayer文件夹和ckplayer.html)到网站根目录,在浏览器 ...
- Ansj分词双数组Trie树实现与arrays.dic词典格式
http://www.hankcs.com/nlp/ansj-word-pairs-array-tire-tree-achieved-with-arrays-dic-dictionary-format ...
- POJ_2104_Kth_(主席树)
描述 http://poj.org/problem?id=2104 给出一个n个数的数列,m次询问,每次询问求区间[l,r]中第k小的数,无修改操作. K-th Number Time Limit: ...
- ruby eclipse调试
rubyinstaller 1.9.3eclipse Keplermarketplace ruby dltk 5.0ruby devkit(Ruby 1.8.7 and 1.9.3) DevKit-t ...
- STM32F0308开发环境的选择--CooCox CoIDE篇
STM32的开发环境有很多总,官方手册也提供了IAR Embedded Workbench.MDK-ARM和TrueSTUDIO这3种.今天我试用了CooCox CoIDE,是免费的集成开发环境,同T ...
- 浅析五大ASP.NET数据控件
转自:http://kb.cnblogs.com/page/69207/ 摘要:ASP.NET中有不少的控件,在这当中有一部分是用来处理数据的控件.在这里我们正要讨论的就是ASP.NET数据控件,希望 ...