POJ1459 Power Network 网络流 最大流
原文链接http://www.cnblogs.com/zhouzhendong/p/8326021.html
题目传送门 - POJ1459
题意概括
多组数据。
对于每一组数据,首先一个数n,表示有n个保安(n=0时输入结束)。
接下来分别描述n个保安的信息。
对于每一个保安,首先两个整数K,M,分别表示他的空余时间段数和他一天中的最多工作时间。
接下来K行,每行h1:m1 h2:m2格式输入两个时间点,表示他从h1:m1时刻到h2:m2时刻是空余的。
现在我们要安排保安。
保安的开始工作和结束工作时间只可以安排在整点或者半点,即m=0或m=30。
现在对于每一组数据,我们问一天中保安数量最少的时刻最多有多少个保安。
题解
网络流学习资源链接 -> 传送门
假如我们已经知道了答案,答案为ans。
那么我们可以考虑判断这个答案的正确性。
我们搞一个超级源点S和一个超级汇点T,然后把所有的保安当作节点,所有的时刻当作节点。
那么我们构图方法就很简单了。
由于保安的开始工作和结束工作时间只可以安排在整点或者半点,所以我们划分一下时刻,把所有的时间段划分成48个。
- 对于每一个保安Pi,我们建立一条S->Pi的边,容量为Mi div 30
- 对于每一个保安Pi,如果他在第Tj个时间段是空闲的,那么我们建立一条Pi->Tj的边,容量为1
- 对于每一个时间点Ti,我们建立一条Ti->T的边,容量为ans
如此建边,我们就只需要跑一跑最大流,然后看最大流是不是等于ans*48就可以了。
于是我们推广出两种算法:
二分答案 VS 逐个添加
本人更倾向于逐个添加,因为网络流的特殊性质。
代码
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
const int N=48+50+5,M=(50*48*2+48+50)*2+233;
bool isd(char ch){
return '0'<=ch&&ch<='9';
}
int read(){
int res=0,f=1;
char ch=getchar();
while (!isd(ch)&&ch!='-')
ch=getchar();
if (ch=='-')
f=-1,ch=getchar();
while (isd(ch))
res=(res<<3)+(res<<1)+ch-48,ch=getchar();
return res*f;
}
int n,Free[1440];
struct edge{
int x,y,cap,flow,nxt;
};
struct gragh{
int cnt,fst[N],dist[N],n,S,T,cur[N],num[N],p[N];
int q[N],head,tail;
edge e[M];
void set(int _S,int _T,int _n){
S=_S,T=_T,n=_n,cnt=1;
memset(fst,0,sizeof fst);
}
void add(int a,int b,int c){
cnt++;
e[cnt].x=a,e[cnt].y=b,e[cnt].cap=c,e[cnt].flow=0;
e[cnt].nxt=fst[a],fst[a]=cnt;
cnt++;
e[cnt].x=b,e[cnt].y=a,e[cnt].cap=0,e[cnt].flow=0;
e[cnt].nxt=fst[b],fst[b]=cnt;
}
void bfs(){
memset(dist,-1,sizeof dist);
head=tail=dist[T]=0,q[++tail]=T;
while (head<tail)
for (int x=q[++head],y,i=fst[x];i;i=e[i].nxt)
if (e[i].cap==0&&dist[y=e[i].y]==-1)
dist[q[++tail]=y]=dist[x]+1;
for (int i=1;i<=n;i++)
if (dist[i]==-1)
dist[i]=n;
}
void init(){
bfs();
memset(num,0,sizeof num);
for (int i=1;i<=n;i++)
num[dist[i]]++,cur[i]=fst[i];
}
int Augment(int &x){
int ex_flow=1e9;
for (int i=T;i!=S;i=e[p[i]].x)
if (e[p[i]].cap-e[p[i]].flow<=ex_flow)
ex_flow=e[p[i]].cap-e[p[i]].flow,x=e[p[i]].x;
for (int i=T;i!=S;i=e[p[i]].x)
e[p[i]].flow+=ex_flow,e[p[i]^1].flow-=ex_flow;
return ex_flow;
}
int ISAP(){
int x=S,y,MaxFlow=0;
init();
while (dist[S]<n){
if (x==T){
MaxFlow+=Augment(x);
continue;
}
bool found=0;
for (int i=cur[x];i;i=e[i].nxt){
y=e[i].y;
if (dist[y]+1==dist[x]&&e[i].cap>e[i].flow){
p[y]=cur[x]=i,x=y,found=1;
break;
}
}
if (!found){
int d=n+1;
for (int i=fst[x];i;i=e[i].nxt)
if (e[i].cap>e[i].flow)
d=min(d,dist[e[i].y]+1);
if (!--num[dist[x]])
return MaxFlow;
num[dist[x]=d]++,cur[x]=fst[x],x=x==S?x:e[p[x]].x;
}
}
return MaxFlow;
}
}g;
bool check(int st,int en){
for (int i=st;i<en;i++)
if (!Free[i])
return 0;
return 1;
}
void solve(){
int S=1,T=2;
g.set(S,T,n+48+2);
for (int i=1;i<=n;i++){
int a=read(),b=read();
memset(Free,0,sizeof Free);
g.add(S,i+2,b/30);
for (int j=1;j<=a;j++){
int h1=read(),m1=read(),h2=read(),m2=read();
int v1=h1*60+m1,v2=h2*60+m2;
if (v1<v2)
for (int k=v1;k<v2;k++)
Free[k]=1;
else {
for (int k=v1;k<1440;k++)
Free[k]=1;
for (int k=0;k<v2;k++)
Free[k]=1;
}
}
for (int j=1;j<=48;j++)
if (check((j-1)*30,j*30))
g.add(i+2,n+j+2,1);
}
int ans=0;
for (int i=1;i<=48;i++)
g.add(n+i+2,T,1);
while (g.ISAP()==48){
ans++;
for (int i=1;i<=48;i++)
g.add(n+i+2,T,1);
}
printf("%d\n",ans);
}
int main(){
while (n=read())
solve();
return 0;
}
POJ1459 Power Network 网络流 最大流的更多相关文章
- POJ 1459 Power Network(网络流 最大流 多起点,多汇点)
Power Network Time Limit: 2000MS Memory Limit: 32768K Total Submissions: 22987 Accepted: 12039 D ...
- POJ-1459 Power Network(最大流)
https://vjudge.net/problem/POJ-1459 题解转载自:優YoU http://user.qzone.qq.com/289065406/blog/1299339754 解题 ...
- POJ1459 Power Network —— 最大流
题目链接:https://vjudge.net/problem/POJ-1459 Power Network Time Limit: 2000MS Memory Limit: 32768K Tot ...
- POJ1459 Power Network(网络最大流)
Power Network Time Limit: 2000MS Memory Limit: 32768K Total S ...
- poj1459 Power Network (多源多汇最大流)
Description A power network consists of nodes (power stations, consumers and dispatchers) connected ...
- Power Network (最大流增广路算法模板题)
Time Limit: 2000MS Memory Limit: 32768K Total Submissions: 20754 Accepted: 10872 Description A p ...
- POJ1459 - Power Network
原题链接 题意简述 原题看了好几遍才看懂- 给出一个个点,条边的有向图.个点中有个源点,个汇点,每个源点和汇点都有流出上限和流入上限.求最大流. 题解 建一个真 · 源点和一个真 · 汇点.真 · 源 ...
- POJ训练计划1459_Power Network(网络流最大流/Dinic)
解题报告 这题建模实在是好建.,,好贱.., 给前向星给跪了,纯dinic的前向星居然TLE,sad.,,回头看看优化,.. 矩阵跑过了.2A,sad,,, /******************** ...
- poj1087 A Plug for UNIX & poj1459 Power Network (最大流)
读题比做题难系列…… poj1087 输入n,代表插座个数,接下来分别输入n个插座,字母表示.把插座看做最大流源点,连接到一个点做最大源点,流量为1. 输入m,代表电器个数,接下来分别输入m个电器,字 ...
随机推荐
- 玩转EhCache之最简单的缓存框架
二.主要特性 快速: 简单: 多种缓存策略: 缓存数据有两级:内存和磁盘,因此无需担心容量问题: 缓存数据会在虚拟机重启的过程中写入磁盘: 可以通过 RMI.可插入 API 等方式进行分布式缓存: 具 ...
- Python- 索引 B+数 比如书的目录
1.索引 为何要有索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题, 在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作, 因此对查询 ...
- python-异常处理、元类
一.异常处理 1.异常处理介绍: 异常是错误发生的信号,一旦程序出错就会产生一个异常,如果该异常没有被应用程序处理,那么该异常就会被抛出来,程序执行随之停止 2.异常通常包含三个部分 1.traceb ...
- 弃 Java 而使用 Kotlin 的你后悔了吗?| kotlin将会是最好的开发语言
自从 2011 年发布以来,Kotlin 凭借强大的功能在开发者中的欢迎程度与日俱增.且在一年前,Google 宣布 Kotlin 正式成为 Android 官方开发语言,由此引发了从 Java 迁移 ...
- PID控制器开发笔记之十一:专家PID控制器的实现
前面我们讨论了经典的数字PID控制算法及其常见的改进与补偿算法,基本已经覆盖了无模型和简单模型PID控制经典算法的大部.再接下来的我们将讨论智能PID控制,智能PID控制不同于常规意义下的智能控制,是 ...
- 前端之css样式(选择器)。。。
一.css概述 CSS是Cascading Style Sheets的简称,中文称为层叠样式表,对html标签的渲染和布局 CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明. 例如 二.c ...
- 基于ajax实现的登录
一.需要知道的新知识点 1.刷新验证码.给src属性加一个?号.加个?会重新去请求 //#给验证码刷新 $(".vialdCode_img").click(function () ...
- 对一个元素 同时添加单击onclick 和 双击ondblclick 触发冲突的解决
需求说明:单击列表项内容后,吧啦吧啦,双击列表项内容后,巴拉巴拉巴拉~~~ 解决思路:卧槽 ,其实我是没思路的,当时唯一的想法就是,看个人点击鼠标的速度了,双击快一点,触发双击事件ლ(′◉❥◉`ლ), ...
- java----static关键字(包括final)
static修饰字段: 使用static关键字修饰一个字段:声明的static变量实际上就是一个全局变量 使用static关键字修饰一个方法:可以直接使用类调用方法,和对象没有关系了 使用static ...
- JS去除空格和换行的正则表达式(推荐)
//去除空格 String.prototype.Trim = function() { return this.replace(/\s+/g, ""); } //去除换 ...