看题解才懂..点击打开链接
这题难在24小时是循环的 需要二分处理 长知识了 还是见得少啊..
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 0x3f3f3f3f
struct node
{
int v;
int w;
int next;
};
queue <int> que;
node edge[2000];
int first[50],need[50],have[50],dis[50],book[50],cnt[50];
int m,num;
void addedge(int u,int v,int w)
{
edge[num].v=v;
edge[num].w=w;
edge[num].next=first[u];
first[u]=num++;
return;
}
bool spfa(int mid)
{
int i,u,v,w;
memset(first,-1,sizeof(first));
num=0;
for(i=1;i<=24;i++)
{
addedge(i-1,i,0);
addedge(i,i-1,-have[i]);
}
for(i=8;i<=24;i++)
{
addedge(i-8,i,need[i]);
}
for(i=1;i<=7;i++)
{
addedge(i+16,i,need[i]-mid);
}
addedge(24,0,-mid);
addedge(0,24,mid);
while(!que.empty()) que.pop();
for(i=0;i<=24;i++)
{
dis[i]=-N;
book[i]=0;
cnt[i]=0;
}
que.push(0);
dis[0]=0;
book[0]=1;
cnt[0]=1;
while(!que.empty())
{
u=que.front();
que.pop();
book[u]=0;
for(i=first[u];i!=-1;i=edge[i].next)
{
v=edge[i].v,w=edge[i].w;
if(dis[v]<dis[u]+w)
{
dis[v]=dis[u]+w;
if(!book[v])
{
que.push(v);
book[v]=1;
cnt[v]++;
if(cnt[v]>24) return false;
}
}
}
}
return true;
}
int binsearch()
{
int l,r,mid,res;
l=0,r=m,res=-1;
while(l<=r)
{
mid=(l+r)/2;
if(spfa(mid))
{
res=mid;
r=mid-1;
}
else
{
l=mid+1;
}
}
return res;
}
int main()
{
int t,i,p,res;
scanf("%d",&t);
while(t--)
{
for(i=1;i<=24;i++)
{
scanf("%d",&need[i]);
}
scanf("%d",&m);
memset(have,0,sizeof(have));
for(i=1;i<=m;i++)
{
scanf("%d",&p);
have[p+1]++;
}
res=binsearch();
if(res==-1) printf("No Solution\n");
else printf("%d\n",res);
}
return 0;
}