题意:给出n个城市,m条边,w个商店,每个商店所属的城市,商品数量,商品单价,q个询问,每次询问给g城市送r个商品在总价不超过a的条件下最小时间,从一个城市到相邻城市所需时间为1。
题解:先按商品价格排序,对于每次询问先bfs出距离此城市的距离,然后二分时间即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<deque>
using namespace std;
typedef long long ll;
ll n,m,cnt,head[5005],shp,vis[5005],g,r,a;
deque<ll>sp;
struct node{
ll to,nex;
}edge[10005];
struct node1{
ll loc,num,pri;
}shop[5005];
void add(ll u,ll v){
edge[cnt].to=v;
edge[cnt].nex=head[u];
head[u]=cnt++;
}
bool cmp(node1 a,node1 b){
return a.pri<b.pri;
}
ll check(ll mid){
ll ans=0,i,dd=r;
for(i=1;i<=shp;i++){
if(vis[shop[i].loc]<=mid){
dd-=shop[i].num;
ans+=shop[i].num*shop[i].pri;
}
if(dd<=0){
ans-=shop[i].pri*(-dd);
break;
}
}
if(dd<=0){
if(ans<=a)return 1;
}
return 0;
}
int main(){
scanf("%lld%lld",&n,&m);
memset(head,-1,sizeof(head));
ll i,j,x,y,q;
for(i=1;i<=m;i++){
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
scanf("%d",&shp);
for(i=1;i<=shp;i++)scanf("%lld%lld%lld",&shop[i].loc,&shop[i].num,&shop[i].pri);
sort(shop+1,shop+1+shp,cmp);
scanf("%d",&q);
while(q--){
scanf("%lld%lld%lld",&g,&r,&a);
for(i=1;i<=n;i++)vis[i]=5005;
while(!sp.empty())sp.pop_front();
sp.push_back(g);
vis[g]=0;
ll l=0,r=n;
while(!sp.empty()){
ll f=sp.front();
sp.pop_front();
for(i=head[f];~i;i=edge[i].nex){
ll v=edge[i].to;
if(vis[v]==5005){
sp.push_back(v);
vis[v]=vis[f]+1;
}
}
}
while(l+1<r){
ll mid=(l+r)/2;
if(check(mid))r=mid;
else l=mid;
}
if(check(l))printf("%lld\n",l);
else if(check(r))printf("%lld\n",r);
else printf("-1\n");
}
return 0;
}