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 本题能够想到用最大流做,那真的是太绝了.建模的方法很 ...
随机推荐
- 由 OR 引起的死循环
在客商迁移测试时,程序一旦开始执行就不能自动停止.只能通过手动中断应用服务器的进程来停止.检查迁移的一个表,这个表迁移前没有数据,迁移最多会插入3w条左右数据,但是迁移过程执行2个多小时候再看,已经有 ...
- ARM GCC 内嵌汇编手册
转自:http://blogold.chinaunix.net/u2/69404/showart_1922655.html ARM GCC 内嵌(inline)汇编手册 关于这篇文档这篇文章是本人为方 ...
- POJ 3258 River Hopscotch 二分枚举
题目:http://poj.org/problem?id=3258 又A一道,睡觉去了.. #include <stdio.h> #include <algorithm> ]; ...
- .Net Framework Data Provider可能没有安装
方法一.下载SQL Server Compact 4.0 安装后就可以解决.下载地址是: http://www.microsoft.com/downloads/zh-cn/details.aspx?f ...
- Java按正则提取字符串
在Java开发中,有时会遇到一些比较别扭的规则从字符串中提取子字符串,规则无疑是写正则表达式来表达了,那按照正则来提取子字符串就会用到java.util.regex包. java.util.regex ...
- 递归-快速排序quickSort
现在对“6 1 2 7 9 3 4 5 10 8”这个10个数进行排序.首先在这个序列中随便找一个数作为基准数.为了方便,就让第一个数6作为基准数吧.接下来,需要将这个序列中所有比基准数 ...
- XE5 安装破解
以下转载自: 盒子 不可以将本破解补丁分享到国外网站.论坛中!低调啊! 本破解补丁只适合中国大陆地区的Delphi.C++Builder爱好者和开发者! 本破解补丁只可用于个人研究交流使用,不得做商 ...
- linux网络配置正确,能够ping通内网地址,无法打开外网网页
在虚拟机里面装了linux后,发现内网能访问,外网访问不了. 首先确定网络配置没有问题,并且能够访问外网,通过以下方法进行确认: [root@localhost ~]# more /etc/sysco ...
- ANDROID_MARS学习笔记_S05_001_用SensorManager获取传感器
1. public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentV ...
- Android软件开发之获取通讯录联系人信息
Android手机的通讯录联系人全部都存在系统的数据库中,如果须要获得通讯里联系人的信息就须要访问系统的数据库,才能将信息拿出来. 这一篇文章我主要带领同学们熟悉Android的通讯录机制. 图中选中 ...