解析
毒瘤题
思路的关键是利用前缀和建图,枚举sum[24]点值
(其实可以二分)
主要是细节的处理不够清晰
使下标从1开始会一下子好做起来
然后把0当做源点
差分约束一定要有源点!!
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=5e5+100;
const double eps=1e-6;
inline ll read() {ll x=0,f=1;char c=getchar();while(!isdigit(c)) {if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return f*x;
}
int n,m;
struct node {int to,nxt;int w;
} p[N<<1];
int fi[N],cnt;
inline void addline(int x,int y,int w) {//printf("%d->%d w=%d\n",x,y,w);p[++cnt]=(node) {y,fi[x],w};fi[x]=cnt;
}
int dis[N];
queue<int>q;
bool vis[N];
int mx;
int tim[N];
bool SPFA() {memset(dis,-0x3f,sizeof(dis));memset(vis,0,sizeof(vis));memset(tim,0,sizeof(tim));while(!q.empty()) q.pop();dis[0]=0;vis[0]=1;q.push(0);while(!q.empty()) {int now=q.front();q.pop();vis[now]=0;//printf("now=%d dis=%d tim=%d\n",now,dis[now],tim[now]);for(int i=fi[now]; ~i; i=p[i].nxt) {int to=p[i].to;if(dis[to]<dis[now]+p[i].w) {//printf(" now=%d to=%d w=%d\n",now,to,p[i].w);dis[to]=dis[now]+p[i].w;tim[to]++;if(tim[to]>24) return false;if(!vis[to]) {q.push(to);vis[to]=1;}}}}return true;
}
int sum[25],r[25],pre[25];
bool work(int x) {memset(fi,-1,sizeof(fi));cnt=-1;for(int i=9; i<=24; i++) addline(i-8,i,r[i]);for(int i=1; i<=8; i++) addline(i+16,i,r[i]-x);for(int i=1; i<=24; i++) {addline(i-1,i,0);addline(i,i-1,-sum[i]);}addline(0,24,x);if(!SPFA()) return false;return true;
}
int main() {
#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifint T=read();while(T--) {int tot=0;memset(sum,0,sizeof(sum));for(int i=1; i<=24; i++) r[i]=read();n=read();for(int i=1; i<=n; i++) {int x=read();x++;sum[x]++;tot++;}//printf("%d\n",work(1));int flag=0;for(int i=0; i<=n; i++) {if(work(i)) {flag=1;printf("%d\n",i);break;}}if(!flag) printf("No Solution\n");}
}
/*
3
intercommunicational
alkylbenzenesulfonate
tetraiodophenolphthalein
0
*/