思路:挺难的一道差分约束 见题解:点击打开链接
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int inf = 0x3f3f3f3f;
int r[30], t[30];
int n;
struct edge
{
int v, cost;
edge() {}
edge(int v, int cost):v(v), cost(cost){}
};
vector<edge> G[30];
void build(int ans)
{
for(int i=0; i<=24; i++) G[i].clear();
G[0].push_back(edge(24, ans));
for(int i=1; i<=24; i++)
{
G[i-1].push_back(edge(i, 0));
G[i].push_back(edge(i-1, -t[i]));
}
for(int i=1; i<=7; i++)
G[i+16].push_back(edge(i, r[i]-ans));
for(int i=8; i<=24; i++)
G[i-8].push_back(edge(i, r[i]));
}
int inque[30], dist[30], _count[30];
int spfa(int ans)
{
memset(inque, 0, sizeof(inque));
memset(_count, 0, sizeof(_count));
for(int i=0; i<=24; i++) dist[i] = -inf;
queue<int> que;
dist[0] = 0;
que.push(0);
inque[0] = 1;
while(!que.empty())
{
int u = que.front(); que.pop();
inque[u] = 0;
for(int i=0; i<G[u].size(); i++)
{
edge e = G[u][i];
int v = e.v, c = e.cost;
if(dist[v] < dist[u]+c)
{
dist[v] = dist[u]+c;
if(!inque[v])
{
inque[v] = 1;
que.push(v);
if(++_count[v] > 24) return false;
}
}
}
}
if(dist[24] == ans)
return true;
return false;
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
memset(r, 0, sizeof(r));
memset(t, 0, sizeof(t));
for(int i=1; i<=24; i++)
scanf("%d", &r[i]);
scanf("%d", &n);
for(int i=0; i<n; i++)
{
int a;
scanf("%d", &a);
a++;
t[a]++;
}
int ans = -1;
for(int i=0; i<=n; i++)
{
build(i);
if(spfa(i))
{
ans = i;
break;
}
}
if(ans == -1)
printf("No Solution\n");
else
printf("%d\n", ans);
}
return 0;
}