2026暑假 [美味绕路] 题解

题目传送门1:
题目传送门2:

这是一道最短路题目,它让我们判断对于每个点,它能不能吃稻草堆让它路径长度减美味值小于等于最短路长度。
我的想法是显然,对于每个点来说,都有一个稻草堆是它要判断是否要吃的,所以把所有稻草堆 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;
}

( ^_^ )

posted on 2026-07-18 11:45  hyh0926  阅读(9)  评论(0)    收藏  举报