poj1149 PIGS 最大流(神奇的建图)
一开始不看题解,建图出错了。后来发现是题目理解错了。
if Mirko wants, he can redistribute the remaining pigs across the unlocked pig-houses.
题目中的这句话非常关键,没理解就错掉了。有很多人写的题解只告诉我们怎么做,却没告诉我们为什么要那样做。
这句话是的意思是可以重组打开过的猪圈。也就是当客人打开猪圈(他能打开的都打开了)以后,他选择了需要买的猪以后,Mirko可以随意把剩下的猪分配到打开的猪圈中。当然,我们追求的是最好的分配方式。
下面来分析样例是怎么来的:
第一个顾客打了了第一、第二个猪圈,选择了两头猪。剩下两头猪。Mirko把这两头猪全部放进了第二个猪圈。根据第三步,可以知道这是最好的分配方式。
第二个顾客打开了第一、第三个猪圈以后,选走了3头。剩下的猪随便分配到第一、第三个猪圈对后面没影响。
第三个顾客打开了第二个猪圈,买走两头。(最多只能有两头,就是第一步分配的)。
2+3+2=7
明白了题意,然后才去向怎么建图。建图的方法其他人的博客里写得非常好了。可以参考他们的.
http://blog.csdn.net/wangjian8006/article/details/7932947 这个博客里有一个网络流建模汇总的链接,可以去下载http://wenku.baidu.com/view/0ad00abec77da26925c5b01c.html
http://www.cnblogs.com/-sunshine/archive/2012/08/21/2648683.html
下面是我的代码:建图用的是链式前向星
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
const int M=*N*N, INF=;
struct node
{
int to,next,w;
}edge[M];
int head[N],numh[N],h[N],cure[N],pre[N],vis[N],flag[N];
int ans,tot;
void SAP(int s, int e,int n)
{
int flow,u,tmp,neck,i;
ans=;
for(i=;i<=n;i++)
cure[i]=head[i];
numh[]=n;
u=s;
while(h[s]<n)
{
if(u==e)
{
flow =INF;
for(i=s;i!=e;i=edge[cure[i]].to)
{
if(flow>edge[cure[i]].w)
{
neck=i;
flow =edge[cure[i]].w;
}
}
for(i=s;i!=e;i=edge[cure[i]].to)
{
tmp=cure[i];
edge[tmp].w-=flow;
edge[tmp^].w+=flow;
}
ans+=flow;
u=neck;
}
for(i=cure[u];i!=-;i=edge[i].next)
if(edge[i].w && h[u]==h[edge[i].to]+) break;
if(i!=-) {cure[u]=i;pre[edge[i].to]=u;u=edge[i].to;}
else
{
if(==--numh[h[u]]) break; //GAP优化
cure[u]=head[u];
for(tmp=n,i=head[u];i!=-;i=edge[i].next)
if(edge[i].w) tmp=min(tmp, h[edge[i].to]);
h[u]=tmp+;
++numh[h[u]];
if(u!=s) u=pre[u];
}
}
}
void init()
{
tot=;
memset(head,-,sizeof(head));
memset(pre,-,sizeof(pre));
memset(h,,sizeof(h));
memset(numh,,sizeof(numh));
memset(vis,,sizeof(vis));
memset(flag,,sizeof(flag));
}
void addedge(int i,int j,int w)
{
edge[tot].to=j;edge[tot].w=w;edge[tot].next=head[i];head[i]=tot++;
edge[tot].to=i;edge[tot].w=;edge[tot].next=head[j];head[j]=tot++;
}
int pg[N];
int main()
{
//猪圈的编号1 ~m ,人的编号是m+1 ~ m+n
//freopen("test.txt","r",stdin);
int m,n,i,j,k,a,b,t,s,e;
while(scanf("%d%d",&m,&n)!=EOF)
{
init();
s=n+; e=s+;
for(i=;i<=m;i++)
{
scanf("%d",&pg[i]);
}
for(k=;k<=n;k++)
{
scanf("%d",&a);
for(i=;i<a;i++)
{
scanf("%d",&j);
if(!vis[j])//猪圈j没有打开过
{
if(!flag[k]) //顾客k没有打开过猪圈
{
addedge(s,k,pg[j]);
flag[k]=tot-;//-2别弄错了
}
else
{
edge[flag[k]].w+=pg[j];
}
vis[j]=k;
}
else
{
addedge(vis[j],k,INF);
vis[j]=k;
}
}
scanf("%d",&b);
addedge(k,e,b);
}
SAP(s,e,e);
printf("%d\n",ans);
}
return ;
}
poj1149 PIGS 最大流(神奇的建图)的更多相关文章
- BZOJ-1822 Frozen Nova 冷冻波 计(jie)算(xi)几何+二分+最大流判定+经典建图
这道逼题!感受到了数学对我的深深恶意(#‵′).... 1822: [JSOI2010]Frozen Nova 冷冻波 Time Limit: 10 Sec Memory Limit: 64 MB S ...
- hdu 3572 Task Schedule(最大流&&建图经典&&dinic)
Task Schedule Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- [NOI2008][bzoj1061] 志愿者招募 [费用流+巧妙的建图]
题面 传送门 思路 引入:网络流? 看到这道题,第一想法是用一个dp来完成决策 但是,显然这道题的数据并不允许我们进行dp,尤其是有10000种志愿者的情况下 那么我们就要想别的办法来解决: 贪心?这 ...
- hdu 2732 Leapin' Lizards 最大流 拆点 建图
题目链接 题意 给定一张网格,格子中有些地方有柱子,有些柱子上面有蜥蜴. 每个柱子只能承受有限只蜥蜴从上面经过.每只蜥蜴每次能走到相距曼哈顿距离\(\leq k\)的格子中去. 问有多少只蜥蜴能走出网 ...
- hdu 2732 Leapin' Lizards (最大流 拆点建图)
Problem Description Your platoon of wandering lizards has entered a strange room in the labyrinth yo ...
- POJ1149 PIGS(最大流)
题意: 有一个人,他有m个猪圈,每个猪圈里面有一定数量的猪,但是每个猪圈的门都是锁着的,他自己没有钥匙,只有顾客有钥匙,一天依次来了n个顾客,(记住是依次来的)他们每个人都有一些钥匙,和他 ...
- 神奇的建图方式(Tarjan)——小z玩游戏
原题来自与:洛谷 P5676(GZOI2017) 链接: https://www.luogu.com.cn/problem/P5676 题面: 题意比较明显,如果已经建好了边,那么跑个Tarjan ...
- POJ1149 PIGS [最大流 建图]
PIGS Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 20662 Accepted: 9435 Description ...
- BZOJ 3144 [HNOI2013]切糕 (最大流+巧妙的建图)
题面:洛谷传送门 BZOJ传送门 最大流神题 把点权转化为边权,切糕里每个点$(i,j,k)$向$(i,j,k+1)$连一条流量为$v(i,j,k)$的边 源点$S$向第$1$层的点连边,第$R+1$ ...
随机推荐
- python利用numpy存取文件
NumPy提供了多种存取数组内容的文件操作函数.保存数组数据的文件可以是二进制格式或者文本格式.二进制格式的文件又分为NumPy专用的格式化二进制类型和无格式类型. numpy格式的文件可以保存为后缀 ...
- PHP stream_socket_server
stream_socket_server - 创建一个Internet或Unix域服务器套接字 描述 资源stream_socket_server(字符串local_socket [摘要和错误号[,串 ...
- jboss的下载安装、环境变量配置以及部署
1. 下载安装 http://jbossas.jboss.org/downloads/ jdk为1.7 我下载的是:JBoss AS7.1.1.Final 2. 解压安装包 D:\program ...
- PAT 1075. PAT Judge
The ranklist of PAT is generated from the status list, which shows the scores of the submittions. Th ...
- firebird的递归查询
with RECURSIVE cte as ( select a.* from PM_PROJECT a where a.pm_id='root_id' union all select k.* fr ...
- 将会改变未来IT世界的十种编程语言
这里要说的都是革新,说这些的目的就是要保持关注最新技术.如果你是一个程序员,想要探寻未来技术,那这篇文章就是你的必读之选.我们这里列出了10种编程语言,10种将会改变IT世界工作方式的编程语言.这些语 ...
- Java并发之CAS与AQS简介
1,什么是CAS CAS(Compare And Swap),即比较并交换.是解决多线程并行情况下使用锁造成性能损耗的一种机制,CAS操作包含三个操作数——内存位置(V).预期原值(A)和新值(B). ...
- ubuntu-ln命令
安装软件完成后,常常需要使用ln命令来将命令重新定义一下路径,就相当于windows中的加入系统环境变量的意思 ~ sudo ln -s /home/spike/Downloads/redis/src ...
- jQuery必知要点(一)
1. jQuery框架的显著特点. jQuery强调的理念是写的少,做的多(write less.do more). 其主要特点有:轻量级.强大的选择器.美丽的DOM操作封装.可靠的事件处理机制.完好 ...
- C语言开发函数库时利用不透明指针对外隐藏结构体细节
1 模块化设计要求库接口隐藏实现细节 作为一个函数库来说,尽力降低和其调用方的耦合.是最主要的设计标准. C语言,作为经典"程序=数据结构+算法"的践行者,在实现函数库的时候,必定 ...