1 条题解
-
0

// 差分约束 SPFA 算法 O(NM*logN) #include<bits/stdc++.h> using namespace std; const int N=25,M=100; int h[N],to[M],ww[M],ne[M],idx; void add(int a,int b,int c){ to[++idx]=b,ww[idx]=c,ne[idx]=h[a],h[a]=idx; } int n; int r[N],num[N]; int d[N],cnt[N],vis[N]; void build(int mid){ idx=0; memset(h,0,sizeof h); for(int i=1; i<=24; i++){ add(i-1,i,0); add(i,i-1,-num[i]); } for(int i=8; i<=24; i++) add(i-8,i,r[i]); for(int i=1; i<=7; i++) add(i+16,i,r[i]-mid); add(0,24,mid); add(24,0,-mid); } bool spfa(int mid){ build(mid); //建图 memset(d,-0x3f,sizeof d); d[0]=0; memset(cnt,0,sizeof cnt); memset(vis,0,sizeof vis); queue<int> q; q.push(0);vis[0]=true; //0就是超级源点 while(!q.empty()){ int u=q.front(); q.pop();vis[u]=false; for(int i=h[u]; i; i=ne[i]){ int v=to[i]; if(d[v]<d[u]+ww[i]){ d[v]=d[u]+ww[i]; //最长路 cnt[v]=cnt[u]+1; //走过的边数 if(cnt[v]>=25) return 1; //有正环 if(!vis[v]) q.push(v),vis[v]=true; } } } return 0; //无正环 } int main(){ int T; cin>>T; while(T--){ for(int i=1; i<=24; i++)cin>>r[i]; //每个时刻的需要人数 cin>>n; memset(num,0,sizeof num); for(int i=1,t; i<=n; i++){ cin>>t; num[t+1]++; //每个时刻的应聘人数 } int l=-1,r=n+1; while(l+1<r){ int mid=l+r>>1; if(!spfa(mid)) r=mid; //如果无正环,说明人多 else l=mid; } if(r==n+1) cout<<"No Solution\n"; else cout<<r<<"\n"; } }
- 1
信息
- ID
- 1482
- 时间
- 1000ms
- 内存
- 10MiB
- 难度
- 3
- 标签
- 递交数
- 30
- 已通过
- 20
- 上传者