RT,小蒟蒻在写代码的时候遇到了下面这种神奇情况:
我认为可能是有 UB,但是我太菜了,找了半天没找出来。
下面附代码(std = C++14)
#include <bits/stdc++.h>
#include <bits/extc++.h>
#define MAXN 5505
#define INF 0x3f3f3f3f
#define P 51
struct pr {
int first, second;
pr(int a, int b) : first(a), second(b) {}
pr() {}
bool operator > (const pr& x) const {
return second > x.second;
}
bool operator == (const pr& x) const {
return first == x.first && second == x.second;
}
};
struct hash_pair {
size_t operator ()(const pr& x) const {
auto h1 = std :: hash <int>{}(x.first);
auto h2 = std :: hash <int>{}(x.second);
return h1 + P * h2;
}
};
typedef std :: priority_queue <pr, std :: vector <pr>, std :: greater <pr> > PR_Q;
typedef __gnu_pbds :: gp_hash_table <pr, int, hash_pair> HS_T;
typedef std :: vector <pr> GR;
int n, T, t[55], a[105], b[105], dis[MAXN], m1, m2, sumt;
bool vis[MAXN];
HS_T mp;
GR G[MAXN];
PR_Q q;
inline void clr() {
sumt = 0;
memset(t, 0, sizeof t);
memset(vis, 0, sizeof vis);
memset(dis, INF, sizeof dis);
HS_T().swap(mp);
PR_Q().swap(q);
for(int i = 1; i <= MAXN; i++)
GR().swap(G[i]);
dis[1] = 0;
return ;
}
inline void dijkstra() {
q.push(pr(1, 0));
while(!q.empty()) {
pr rhs = q.top();
q.pop();
if(vis[rhs.first])
continue ;
vis[rhs.first] = true;
for(pr v : G[rhs.first]) {
int to = v.first, wt = v.second;
if(dis[to] > dis[rhs.first] + wt) {
dis[to] = dis[rhs.first] + wt;
q.push(pr(to, dis[to]));
}
}
}
return ;
}
inline int genGraph() {
int V = 0;
pr st = pr(0, 0); mp[st] = ++V;
int tmpp[105][252];
memset(tmpp, INF, sizeof tmpp);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m1; j++) {
if(t[i] + a[j] > T)
continue ;
pr tmp = pr(i, t[i] + a[j]);
tmpp[i][j] = t[i] + a[j];
if(mp[tmp] == 0)
mp[tmp] = ++V;
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m2; j++) {
if(sumt + b[j] > t[i] + T)
continue ;
pr tmp = pr(i, sumt - t[i] + b[j]);
tmpp[i][j + m1] = sumt - t[i] + b[j];
if(mp[tmp] == 0)
mp[tmp] = ++V;
}
for(int i = 1; i <= n; i++)
std :: sort(tmpp[i] + 1, tmpp[i] + m1 + m2 + 1);
pr ed = pr(n + 1, T); mp[ed] = ++V;
for(int i = 1; i < n; i++)
for(int j = 1; j <= m1; j++) {
if(t[i] + a[j] > T || t[i + 1] + a[j] > T)
continue ;
pr ux = pr(i, t[i] + a[j]); pr vx = pr(i + 1, t[i + 1] + a[j]);
G[mp[ux]].push_back(pr(mp[vx], 0));
}
for(int i = 2; i <= n; i++)
for(int j = 1; j <= m2; j++) {
if(sumt + b[j] > t[i] + T || sumt + b[j] > t[i - 1] + T)
continue ;
pr ux = pr(i, sumt - t[i] + b[j]); pr vx = pr(i - 1, sumt - t[i - 1] + b[j]);
G[mp[ux]].push_back(pr(mp[vx], 0));
}
for(int i = 1; i <= n; i++)
for(int j = 1; j < m1 + m2; j++) {
if(tmpp[i][j] > T || tmpp[i][j + 1] > T)
continue ;
pr ux = pr(i, tmpp[i][j]); pr vx = pr(i, tmpp[i][j + 1]);
G[mp[ux]].push_back(pr(mp[vx], tmpp[i][j + 1] - tmpp[i][j]));
}
for(int i = 1; i <= m1 + m2; i++) {
pr ux = pr(n, tmpp[n][i]); pr vx = pr(1, tmpp[1][i]);
if(tmpp[1][i] <= T)
G[1].push_back(pr(mp[vx], tmpp[1][i]));
if(T >= tmpp[n][i])
G[mp[ux]].push_back(pr(V, T - tmpp[n][i]));
}
return V;
}
int main() {
int pcnt = 0;
scanf("%d", &n);
do {
++pcnt;
clr();
scanf("%d", &T);
int dt = 0;
for(int i = 2; i <= n; i++) {
scanf("%d", &dt);
t[i] = dt + t[i - 1];
sumt += dt;
}
scanf("%d", &m1);
for(int i = 1; i <= m1; i++)
scanf("%d", a + i);
scanf("%d", &m2);
for(int i = 1; i <= m2; i++)
scanf("%d", b + i);
int edx = genGraph();
dijkstra();
if(dis[edx] == INF)
printf("Case Number %d: impossible\n", pcnt);
else
printf("Case Number %d: %d\n", pcnt, dis[edx]);
scanf("%d", &n);
}while(n != 0);
return 0;
}