此题约束条件较多。
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#define N 30
#define M 100
#define MAXQ 10000
using namespace std;
const int inf = (-1u >> 1);
int R[24], t[24];
int s[N];
int d[N], first[N];
int u[M], v[M] , w[M], next[M];
bool inq[N];
int cnt[N];
int e;
int q[MAXQ];
void addE(int x, int y, int c)
{
next[e] = first[x], first[x] = e;
u[e] = x, v[e] = y;
w[e] = c;
e++;
}
void init(int sum)
{
e = 0;
for (int i = 0; i <= 24; i++)
first[i] = -1;
for (int i = 0; i < 16; i++)
{
addE(i, i + 8, R[i + 8]);
}
for (int i = 16; i < 24; i++)
{
addE(i, (i + 8)%24, R[(i + 8)% 24] - sum);
}
for (int i = 0; i < 23; i++)
{
addE(i, i + 1, 0);
addE(i + 1, i, -t[i + 1]);
}
addE(24, 0, 0);
addE(0, 24, -t[0]);
addE(24, 23, sum);
}
bool SPFA(int s, int n, int sum)
{
for (int i = 0; i < n; i++)d[i] = -inf;
memset(cnt, 0, sizeof(cnt));
d[s] = 0;
int qs, qe;
qs = qe = 0;
for (int i = 0; i < n; i++)inq[i] = false;
q[qe++] = s;
while (qs < qe)
{
int x = q[qs++];
inq[x] = false;
for (int e = first[x]; e != -1; e = next[e])if (d[v[e]] < d[u[e]] + w[e])
{
d[v[e]] = d[u[e]] + w[e];
if (!inq[v[e]])
{
inq[v[e]] = true;
q[qe++] = v[e];
if (++cnt[v[e]] >= n)return false;
}
}
}
return true;
}
int main()
{
int ca;
scanf("%d", &ca);
int m;
// FILE* fp = fopen("in.txt", "r");
while (ca--)
{
for (int i = 0; i < 24; i++)
{
scanf( "%d", R + i);
}
scanf( "%d", &m);
int tmp;
memset(t, 0, sizeof(t));
for (int i = 0; i < m; i++)
{
scanf( "%d", &tmp);
t[tmp]++;
}
bool flag = false;
int l = 0, r = m + 1;
int mid , ans = -1;
while (l + 1 < r)
{
mid = ((l + r) / 2);
init(mid);
flag = SPFA(24, 25, mid);
if (flag)
r = mid, ans = mid;
else l = mid;
}
if ( ans > 0 && ans < m + 1)printf("%d\n", ans);
else puts("No Solution");
}
return 0;
}