1. 程式人生 > >poj 1275 Cashier Employment 差分約束

poj 1275 Cashier Employment 差分約束

#include <bits/stdc++.h>
using namespace std;
#define ULL unsigned long long
#define LL long long
const LL mod=998244353;
const int maxn=20+10;
const int n=24;
int r[maxn];
int b[maxn];
struct edge{int u,v,w;};
vector<edge>e;
void addedge(int u,int v,int w)
{
   e.push_back((edge){u,v,w});
}
//d_i 前i小時一共需要僱傭的人數 //b_i 第i小時開始時可以上班的人數 //r_i 第i小時需要工作的人數 // d_(i-1)-d_i<=0 d_i遞增 // d_i-d_(i-1)<=b_i 第i小時僱傭的人應小於該小時能開始上班的人數 // d_(i-8)-d_i<=-r_i 每8個小時段一共開始上班的人數滿足第i個小時的需求 // d_(i+16)-d_i<=limit-r_i 同上,該超市是[每天]24小時營業 // d_0-d_24<=-limit int dis[maxn]; #define u (i.u) #define v (i.v) #define w (i.w) int
spfa(int val) { e.clear(); for(int i=1;i<=n;i++) addedge(i,i-1,0),addedge(i-1,i,b[i]); for(int i=9;i<=24;i++) addedge(i,i-8,-r[i]); for(int i=1;i<=8;i++) addedge(i,i+16,val-r[i]); // addedge(0,24,val); addedge(24,0,-val); memset(dis,0x3f,sizeof dis);dis[0
]=0; for(int i=1;i<n;i++) for(auto& i:e) dis[v]=min(dis[u]+w,dis[v]); for(auto& i:e) if(dis[v]>dis[u]+w) return false; // printf("%d %d %d\n",dis[0],dis[24],-val); return true; } #undef u #undef v #undef w int main() { #ifdef shuaishuai freopen("in.txt","r",stdin); // freopen("in.out","w",stdout); #endif // shuaishuai int t; scanf("%d",&t); while(t--) { for(int i=1;i<=n;i++) { scanf("%d",r+i); b[i]=0; } int m; scanf("%d",&m); for(int i=0,x;i<m;i++) { scanf("%d",&x);b[x+1]++; } int res=-1,l=0,r=m,mid; while(l<=r) { mid=(l+r)/2; if(spfa(mid)) r=mid-1,res=mid; else l=mid+1; } if(res==-1) puts("No Solution"); else printf("%d\n",res); // int i; // for(i=0;i<=m;i++) // if(spfa(i)) break; // if(i<=m) printf("%d\n",i); // else puts("No Solution"); } return 0; }