您的位置:首页 > 其它

pku 1275 Cashier Employment

2011-08-15 12:53 120 查看
【题目大意】: 给出一个超市24小时各需要R[i]个雇员工作,有N个雇员可以雇佣,他们开始工作时间分别为A[i],求需要的最少的雇员人数。

这题目在黑书上有详细的解析,题目的关键是在构图上,把约束条件找出来,再按照条件加边就OK了,不过,我是参考课件里面才过的

【算法分析】: 用差分约束,难点是建立模型。设X[i]为0-i小时内工作的人数(X[24]即为所求),R[i]为第(i-1)-i小时时需要在工作的人数,A[i]可以在第i-1小时开始工作。可以建立起以下约束不等式:

0 <= X[i]-X[i-1] <= A[i]; 1 <= I <= 24;

X[i] – X[i-8] >= R[i]; 8 <= I <= 24;

X[24] – (X[16+i]-X[i]) >= R[i]; 1 <= I < 8;

统一化为<=不等式,则可化为求X[0]-X[24] <= --ans; 即求24到0的最短距离。如果化为>=不等式,则比较直观,X[24]- X[0] >= ans; 求0到24的最长距离。如果有圈出现则无解。二分答案找到最小的ans,使得约束系统有解。特别注意一点,X[24]-X[0] >= ans也是要作为一个约束不等式,添加(0, 24, ans)的边。

#include<iostream>
#include<string>
#define MAXINT 9999999
#define MAXN 30
using namespace std;
int dis[MAXN],num;
int n,m,r[25],t[25];
//r[],(i-1)-i小时内需要工作人数.
//t[],第(i-1)小时可以开始工作的人数.
struct edge
{
int u,w,v;
}e[MAXN*5];
void add(int u,int v,int w)
{
e[num].u=u;
e[num].w=w;
e[num].v=v;
num++;
}
bool bellman_ford()
{
for(int i=0;i<=24;i++)
dis[i]=-MAXINT;
dis[24]=0;
bool rel=false;
for(int i=1;i<=24;i++)
{
for(int j=0;j<num;j++)
{
int x=e[j].v;
if(dis[x]>dis[e[j].u]+e[j].w)
{
dis[x]=dis[e[j].u]+e[j].w;
rel=true;
}
}
if(!rel) //没有可松弛操作,则一定有解了
return true;
}
for(int j=0;j<num;j++)
{
int x=e[j].v;
if(dis[x]>dis[e[j].u]+e[j].w)
return false;
}
return true;
}
int main()
{
int n1,cas,a,minn,maxn;
cin>>cas;
while(cas--)
{
minn=-1;
memset(t,0,sizeof(t));
for(int i=1;i<=24;i++)
{
cin>>r[i];
if(r[i]>minn) minn=r[i];
}
cin>>n1;
maxn=n1;
//因为最少要有max(r[i])个人,最多有n1个人。
for(int i=0;i<n1;i++)
{
cin>>a;
t[++a]++;
}
num=0;
for(int i=1;i<=24;i++)
{
add(i-1,i,t[i]);
add(i,i-1,0);
}
for(int i=8;i<=24;i++)
add(i,i-8,-r[i]);
int edge_num=num;//edge_num保存已经加好的边数
int res=-1;
int left=minn,right=maxn,mid;
while(left<=right)//二分枚举答案
{
num=edge_num;
mid=(right+left)/2;
for(int i=1;i<8;i++)
add(i,i+16,-r[i]+mid);
add(24,0,-mid);
//这里其实有个隐藏的约束条件X[24]-X[0]>=mid
//转换为X[0]-X[24] <= -mid;
if(bellman_ford())//如果有解,那么再找更小的解
{
right=mid-1;res=mid;
}
else left=mid+1;
}
if(res==-1)
cout<<"No Solution"<<endl;
else cout<<res<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: