解析
毒瘤题
思路的关键是利用前缀和建图,枚举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_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
int 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
*/