题目:http://poj.org/problem?id=1275

做的第一道差分约束题...

首先,根据题意得出一些不等关系(f为前缀和雇佣人数):

0 <= f[i] - f[i-1] <= t[i];      // 雇佣的人数少于申请者但不能为负数
f[i] - f[i-8] >= r[i]              // 当x>=8时,该方程成立,否则将出现负数显然不成立
f[i-8+24] - f[i] <= x - r[i]   // 当x<8时,由于昨天的雇人可以通宵上班,因此这个约束通过反面处理
f[24] - f[0] >= x              // 最后24小时内雇佣人应该大于等于x个人

其中x是一个需要二分的变量,也就是最终雇佣了多少人;

而最后一个条件,可以看做是强制选x个人,那么即使实际上雇佣了小于x的人,spfa结果仍为(-)x,这样可以来判断x是否为可行解;

千辛万苦终于AC,最后迟迟难A的问题竟然是spfa中没有给vis数组赋0!这是习惯错误,因为这个spfa与平常不同的是有中途return 0,所以可能没有把vis全赋会0就退出,所以每次需要重新赋0。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
queue<int>q;
int const MAXN=;
int T,n,r[MAXN],t[MAXN],ct,head[MAXN],L,R,dis[MAXN],cnt[MAXN];
bool vis[MAXN];
struct N{
int to,next,w;
N(int t=,int n=,int w=):to(t),next(n),w(w) {}
}edge[MAXN*];
bool spfa(int x)
{
while(q.size())q.pop();
memset(dis,0x3f,sizeof dis);
memset(cnt,,sizeof cnt);
memset(vis,,sizeof vis);//!!!
int s=;
q.push(s);vis[s]=;dis[s]=;cnt[s]=;
//根据加边看到应该从后往前走,从-x人出发,dis为负
while(q.size())
{
int x=q.front();q.pop();vis[x]=;
if(cnt[x]>)return ;//若入队>25次,可判断存在负环
for(int i=head[x];i;i=edge[i].next)
{
int u=edge[i].to;
if(dis[u]>dis[x]+edge[i].w)
{
dis[u]=dis[x]+edge[i].w;
if(!vis[u])vis[u]=,q.push(u),cnt[u]++;
}
}
}
return dis[]==-x;//是否的确雇佣了x个人(没有被边限制卡掉)
}
bool pd(int x)
{
ct=;
memset(head,,sizeof head);
for(int i=;i<;i++)
{
edge[++ct]=N(i+-,head[i],x-r[i]);head[i]=ct;
edge[++ct]=N(i,head[i-],t[i]);head[i-]=ct;
edge[++ct]=N(i-,head[i],);head[i]=ct; }
for(int i=;i<=;i++)
{
edge[++ct]=N(i-,head[i],-r[i]);head[i]=ct;
edge[++ct]=N(i,head[i-],t[i]);head[i-]=ct;
edge[++ct]=N(i-,head[i],);head[i]=ct;
}
edge[++ct]=N(,head[],-x);head[]=ct;//!f[24]-f[0]>=x
return spfa(x);
}
int main()
{
scanf("%d",&T);
while(T--)
{
for(int i=;i<=;i++)
scanf("%d",&r[i]);
scanf("%d",&n);
for(int i=;i<=n;i++)
{
int x;
scanf("%d",&x);
t[x+]++;//从1~24计算
}
L=;R=n;
int ans=-;
while(L<=R)
{
int mid=((L+R)>>);
if(pd(mid))ans=mid,R=mid-;
else L=mid+;
}
if(ans!=-)printf("%d\n",ans);
else printf("No Solution\n");
}
return ;
}

poj1275收银员——差分约束的更多相关文章

  1. 【POJ1275】Cashier Employment 差分约束

    [POJ1275]Cashier Employment 题意: 超市经历已经提供一天里每一小时需要出纳员的最少数量————R(0),R(1),...,R(23).R(0)表示从午夜到凌晨1:00所需要 ...

  2. 湖南附中模拟day1 收银员

    4.1 题意描述花花家的超市是 24 小时营业的,现在需要招聘收银员.超市每个小时都需要不同数量的收银员,用 ai 表示一天中 i 点到 i + 1 点这一小时内需要的收银员数量,特别地 a23 表示 ...

  3. 【NOIP模拟赛】收银员(一道差分约束好题)

    /* s[]表示最优方案的序列中的前缀和,那么s[23]就是最优方案 由题意我们可以列出这样一些式子: s[i]+s[23]-s[16+i]>=a[i] (i-8<0) s[i]-s[i- ...

  4. Acwing 393. 雇佣收银员

    算法1: 差分约束 + 枚举 O(Tn2028) 由于牵扯到 \([i - 8 + 1, i]\) 这段区间的和的约束,所以用前缀和更好表达一些. 设 \(num[i]\)表示 \(i\) 时刻有多少 ...

  5. POJ1275 Cashier Employment 【二分 + 差分约束】

    题目链接 POJ1275 题解 显然可以差分约束 我们记\(W[i]\)为\(i\)时刻可以开始工作的人数 令\(s[i]\)为前\(i\)个时刻开始工作的人数的前缀和 每个时刻的要求\(r[i]\) ...

  6. 移动零售批发行业新的技术特色-智能PDA手持移动扫描打印销售开单收银仪!!

    提起便利店或者超市,大家的第一印象一定是前台那个笨重的POS机和站在POS机后的收银员.传统的零售店中,笨重的POS机随处可见. 变革前,零售盘点多烦忧 一个顾客要结账,就需要通过POS机.小票打印机 ...

  7. C++ 大作业 超市收银系统

    #include<iostream> #include<fstream> #include<string> #include<iomanip> #inc ...

  8. POJ1275/ZOJ1420/HDU1529 Cashier Employment (差分约束)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 题意:一商店二十四小时营业,但每个时间段需求的出纳员不同,现有n个人申请这份工作, ...

  9. POJ1275出纳员的雇佣【差分约束】

    出纳员的雇佣 Tehran的一家每天24小时营业的超市,需要一批出纳员来满足它的需要.超市经理雇佣你来帮他解决问题:超市在每天的不同时段需要不同数目的出纳员(例如:午夜时只需一小批,而下午则需要很多) ...

随机推荐

  1. LeetCode 205 Isomorphic Strings(同构的字符串)(string、vector、map)(*)

    翻译 给定两个字符串s和t,决定它们是否是同构的. 假设s中的元素被替换能够得到t,那么称这两个字符串是同构的. 在用一个字符串的元素替换还有一个字符串的元素的过程中.所有字符的顺序必须保留. 没有两 ...

  2. python入门之搭建环境

    进入以下网站:python.org 选择你喜欢(需要)的版本下载 点击下载即可,本次提供下载:python3.6.3 (国外架设,非常慢) ,用百度的平台吧:python3.6.1,多谢百度. 开始安 ...

  3. dos alias/cname address

    diego@localhost sdk/include/Poco/Net]# dig b.wpss.cn ; <<>> DiG - <<>> b.wps ...

  4. soapUI学习笔记--用例字段参数化

    字段参数化的简单操作 1.把Request新增一个TestCase 增加TestCase,下方会出现: 2.案例中,请求参数只有一个.先运行下请求,可以运行成功(保证接口是通的) 3.添加参数.见图中 ...

  5. C++零基础到入门

    (1)C语言概述 (2)编写.运行一个简单的C语言程序 (3)数据类型 (4)运算符和表达式 如果你对C语言一窍不通,那你就好好看这篇文章,我会力争让你真正的做到从零基础到入门,同时这篇文章会让你基本 ...

  6. Linux(centos 6.5) 调用java脚本以及定时运行的脚本实例及配置文件具体解释

    Linux(centos 6.5) 调用java脚本以及定时运行的脚本实例 一.调用java程序脚本(默认已经搭建好了Java环境) 1.jdk 安装路径 /usr/jdk/jdk1.7/-- 2.j ...

  7. 关于 angular cookie 设置的坑

    初识Angular,才知道掉进了这么一个各种大坑的坑. 先说下对于$cookie.put 这几个方法,只有1.4以上版本才可以用,其余低于版本请使用 $cookieStore: 下面举例下使用方法: ...

  8. MAC如何查看某个端口的占用情况

    执行如下命令: lsof -i tcp:8080 #8080为查询的端口号 会展示该端口的使用情况,然后kill -9 PID的值即可关闭该端口

  9. React Native组件解析(二)之Text

    React Native组件解析(二)之Text 1. 概述 Text组件对应于iOS的UILabel,Android的TextView,用来显示文本.但是Text组件的内部使用的并不是flexbox ...

  10. innodb的锁和高并发

    1 innodb的锁 1.1 s锁,即读锁,即share锁 1.2 x锁,即写锁,排他锁 1.3 s锁和x锁之间的关系 多个读锁可以共存,但是读锁不可以和写锁共存.写锁和写锁不可以共存. 1.4 间隙 ...