2026暑假 [美味绕路] 题解
这是一道最短路题目,它让我们判断对于每个点,它能不能吃稻草堆让它路径长度减美味值小于等于最短路长度。
我的想法是显然,对于每个点来说,都有一个稻草堆是它要判断是否要吃的,所以把所有稻草堆 push 进 \(dijkstra\) 的入点,去进行一个多源最短路。
但是这是就会出现一个情况,比如一个稻草堆离点更近,但是它的美味值太小了,导致它不是最优的。
我们可以将每个稻草堆的美味值减去它到 \(n\) 的距离,再做上面操作就对了。
代码 $\downarrow$
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,k,kk[50005],k3[50005];
int dij[50005];
bool f[50005],g[50005],f2[50005];
bool ans[50005];
vector<pair<int,int> >v[50005];
priority_queue<pair<int,pair<int,int> >,vector<pair<int,pair<int,int> > >,greater<pair<int,pair<int,int> > > >pq;
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >pq2;
void dijk2()
{
pq2.push(make_pair(0,n));
while(!pq2.empty())
{
int x=pq2.top().first;
int y=pq2.top().second;
pq2.pop();
if(f2[y])continue;
dij[y]=x;
if(g[y])k3[y]-=dij[y];
f2[y]=1;
for(int i=0;i<v[y].size();i++)
{
pq2.push(make_pair(x+v[y][i].second,v[y][i].first));
}
}
return;
}
void dijk()
{
for(int i=1;i<=k;i++)
{
pq.push(make_pair(-k3[kk[i]],make_pair(kk[i],kk[i])));
}
while(!pq.empty())
{
int x=pq.top().first;
int y=pq.top().second.first;
int z=pq.top().second.second;
pq.pop();
if(f[y])continue;
if(x<=dij[y])ans[y]=1;
f[y]=1;
for(int i=0;i<v[y].size();i++)
{
pq.push(make_pair(x+v[y][i].second,make_pair(v[y][i].first,z)));
}
}
return;
}
signed main()
{
freopen("dining.in","r",stdin);
freopen("dining.out","w",stdout);
cin>>n>>m>>k;
for(int i=1;i<=m;i++)
{
int x,y,z;
cin>>x>>y>>z;
v[x].push_back(make_pair(y,z));
v[y].push_back(make_pair(x,z));
}
for(int i=1;i<=k;i++)
{
int x;
cin>>kk[i]>>x;
k3[kk[i]]=x;
g[kk[i]]=1;
}
dijk2();
dijk();
for(int i=1;i<n;i++)cout<<ans[i]<<"\n";
return 0;
}
( ^_^ )
浙公网安备 33010602011771号