又一次不记得自己是怎么写的了...
Cashier Employment 出纳员问题
问题描述
有一家24小时营业的超市,需要雇佣一批出纳员。一天中每个小时需要出纳员的最少数量为R0,R1,R2,...,R23。有N个人申请这项工作,每个申请者,从一个特定时刻Ti,开始连续工作恰好8个小时。(Ti为整数,且 0<=Ti<=23 )
你的任务是计算出需要雇佣出纳员的最少数目,满足在每一时刻k,至少有Ri名出纳员在工作。
输入
第一行一个数T(T<=20),表示测试数据的个数。
对于每一个测试数据,第一行24个整数R0,R1,R2,...,R23,用空格分开。接下来的一行一个数N。然后接下来有N行,每一行有一个数Ti,表示第i个申请人在Ti时刻开始工作。
输出
对于每一个测试数据,仅包含一行,如果有答案,就输出最少出纳员的数目,反之则输出’ No Solution’。
样例输入
1
1 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
5
0
23
22
1
10
样例输出
1
1 #include<iostream> 2 #include<stdio.h> 3 #include<string.h> 4 #include<algorithm> 5 #include<queue> 6 #define INF 0xfffffff 7 using namespace std; 8 struct list 9 { 10 int r; 11 int len; 12 int next; 13 }node[500000]; 14 int head[100000]; 15 int r[10000];//需要人数 16 int t[10000];//应征人数 17 int num=0; 18 int s[10000];//0-i雇佣人数 19 int dist[10000]; 20 queue<int>q; 21 void add(int x,int y,int z) 22 { 23 node[num].r=y; 24 node[num].len=z; 25 node[num].next=head[x]; 26 head[x]=num++; 27 } 28 void dos(int x) 29 { 30 int i; 31 memset(head,-1,sizeof(head)); 32 add(0,24,x); 33 for(i=1;i<=24;i++) 34 { 35 add(i-1,i,0); 36 add(i,i-1,-t[i]); 37 } 38 for(i=1;i<=16;i++) 39 { 40 add(i,i+8,r[i+8]); 41 } 42 for(i=17;i<=24;i++) 43 { 44 add(i,i-16,r[i-16]-x); 45 } 46 } 47 int spfa(int x) 48 { 49 int i; 50 while(!q.empty())q.pop(); 51 for(i=0;i<=25;i++)dist[i]=-INF; 52 dist[0]=0; 53 q.push(0); 54 int vis[100]; 55 int time[100]; 56 memset(time,0,sizeof(time)); 57 memset(vis,0,sizeof(vis)); 58 vis[0]=1; 59 time[0]=1; 60 while(!q.empty()) 61 { 62 int e; 63 e=q.front(); 64 q.pop(); 65 vis[e]=0; 66 for(i=head[e];i!=-1;i=node[i].next) 67 { 68 int v=node[i].r; 69 if(dist[v]<dist[e]+node[i].len) 70 { 71 dist[v]=dist[e]+node[i].len; 72 if(!vis[v]) 73 { 74 vis[v]=1; 75 q.push(v); 76 time[v]++; 77 if(time[v]>24)return -1; 78 } 79 } 80 } 81 } 82 if(dist[24]==x)return 1; 83 else return 0; 84 } 85 int main() 86 { 87 int T,i,n,x; 88 scanf("%d",&T); 89 while(T--) 90 { 91 memset(r,0,sizeof(r)); 92 memset(t,0,sizeof(t)); 93 for(i=1;i<=24;i++) 94 { 95 scanf("%d",&r[i]); 96 } 97 scanf("%d",&n); 98 for(i=0;i<n;i++) 99 { 100 scanf("%d",&x); 101 t[x+1]++; 102 } 103 for(i=0;i<=n;i++) 104 { 105 dos(i); 106 if(spfa(i)>0) 107 { 108 printf("%d\n",i); 109 break; 110 } 111 } 112 if(i==n+1) 113 { 114 printf("No Solution\n"); 115 } 116 } 117 return 0; 118 }