NC22594 Rinne Loves Graph——Dijstra+一点点条件

题目传送门

文章目录

题意

在至多经过k个戒严城市条件下求1到n的最短路,如果不能到达输出-1

题解

  • emmm,网上看到许多大佬说分层图,还有dp,蒟弱实在不懂。这道题的简单解法就是Dijstra加上一点限制条件
  • 结构体里有三个元素,p: 当前点。d: 起点到当前点的最短距离。cnt:从起点到点p“穿过”的次数
  • dist数组更新条件:在这里插入图片描述

AC代码

#include<bits/stdc++.h>

using namespace std;
#define N 10009
#define M 20009
#define mem(a,b) memset(a,b,sizeof a)
#define ll long long
#define PII pair<ll,int> 
#define INF 0x3f3f3f3f
int n,m,k,u,v,W;
int h[N],e[N],ne[N],w[N],idx,is[N];
int dist[N],st[N];
void add(int x,int y,int z)
{
	e[idx] = y;
	w[idx] = z;
	ne[idx] = h[x];
	h[x] = idx++;
}
struct node
{
	int d,p,cnt;//cnt记录从起点到点p穿过戒严城市次数 
	bool operator < (const node &t) const
	{
		return d>t.d;
	}
};
int Dijstra()
{
	mem(dist,0x3f);
	dist[1] = 0;
	priority_queue<node> heap;
	//初始时在起点,即使起点是戒严城市,穿过次数也为0
	//因为还没穿过呢 
	heap.push({0,1,0});
	while(heap.size())
	{
		node tmp = heap.top();
		heap.pop();
		int p = tmp.p,d = tmp.d,cnt=tmp.cnt;
		if(st[p]) continue;
		st[p] = 1;
		for(int i=h[p]; i!=-1; i=ne[i])
		{
			int j = e[i];
			//dist数组更新的条件加上穿过戒严城市的次数<=k 
			if(dist[j]>d+w[i]&&cnt+is[p]<=k)
			{	
				dist[j] = d+w[i];
			    heap.push({dist[j],j,cnt+is[p]});	
			}
		}
	}
	if(dist[n]>=INF) return -1;
	return dist[n];
}
int main()
{
	mem(h,-1);
	cin>>n>>m>>k;
	for(int i=1; i<=n; i++) scanf("%d",is+i);
	for(int i=1; i<=m; i++)
	{
		scanf("%d%d%d",&u,&v,&W);
		add(u,v,W);
		add(v,u,W);
	}
	printf("%d",Dijstra()); 
	return 0;
 } 

参考牛客大佬博客
有错误请指出呀,不懂得也可以问问我,大家一起进步!

posted @ 2022-08-28 08:44  翔村亲亲鸟  阅读(9)  评论(0编辑  收藏  举报