http://poj.org/problem?id=1275
题意 : 一家24小时营业的超市,要雇出纳员,需要求出超市每天不同时段需要的出纳员数,午夜只需一小批,下午需要多些,希望雇最少的人,给出每小时需要的出纳员的最少数量,R(0),R(1),...,R(23)。R(0)表示从午夜到凌晨1:00所需要出纳员的最少数目;R(1)表示凌晨1:00到2:00之间需要的;以此类推。这些数据每一天都是相同的。有N人申请这工作,申请者 i ,从一个特定的时刻开始连续工作恰好8小时。定义ti(0<=ti<=23)为上面提到的开始时刻,也就是说,如果第i个申请者被录用,他)将从 ti 时刻开始连续工作8小时。
思路 :差分约束,挺难的,看了好多人的题解,才稍微懂一些了,http://972169909-qq-com.iteye.com/blog/1185527,这个神写的不错,,,还有黑书上也有解释
其实说的有点那啥,我一开始也还是没怎么看懂
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <stdio.h> #include <string.h> #include <queue> using namespace std; const int INF = 9999999 ; struct node { int u,v,w ; int next ; } map[250] ; bool flag[25] ; int cnt,pre[25],cntt[25],dist[25] ; int r[25],t[26] ; void addedge(int u,int v,int w) { map[cnt].v = v ; map[cnt].w = w ; map[cnt].next = pre[u] ; pre[u] = cnt++ ; } void Init() { cnt = 0 ; memset(pre,-1,sizeof(pre)) ; memset(cntt,0,sizeof(cntt)) ; memset(flag,false,sizeof(flag)) ; } bool spfa(int start) { queue<int >Q ; for(int i = 0 ; i < 25 ; i++) dist[i] = -INF ; dist[start] = 0 ; Q.push(start) ; flag[start] = true ; while(!Q.empty()) { int u = Q.front() ; Q.pop() ; if(++cntt[u] > 24) return false ; flag[u] = false ; for(int i = pre[u] ; i + 1 ; i = map[i].next) { int v = map[i].v ,w = map[i].w; if(dist[v] < dist[u] + w) { dist[v] = dist[u] + w ; if(!flag[v]) { flag[v] = true ; Q.push(v) ; } } } } return true ; } int main() { int T ; scanf("%d",&T) ; while(T--) { for(int i = 1 ; i <= 24 ; i++) scanf("%d",&r[i]) ; int N ,s; scanf("%d",&N) ; memset(t,0,sizeof(t)) ; for(int i = 0 ; i < N ; i++) { scanf("%d",&s) ; t[s + 1]++ ; } int low = 0 ,high = N ; bool flagg = false ; while(low < high) { Init() ; int mid = (low+high)>>1 ; for(int i = 1 ; i <= 24 ; i++) { addedge(i-1,i,0) ; addedge(i,i-1,-t[i]) ; } for(int i = 8 ; i <= 24 ; i++) addedge(i-8,i,r[i]) ; for(int i = 1 ; i <= 7 ; i++) addedge(i+16,i,r[i]-mid) ; addedge(0,24,mid) ; if(spfa(0)) { high = mid ; flagg = true ; } else low = mid+1 ; } if(flagg) printf("%d ",high) ; else printf("No Solution ") ; } return 0; }