飞行路线(分层最短路模板)

题目连接:https://ac.nowcoder.com/acm/problem/20131

思路:

建立原图的基础上再建立k个分身,每个分身之间的权值为0,用dijkstra算起始点到各点的距离,注意k次免费的机会不一定都使用。

画个图大家就明白了。

 

这就相当于在用掉最多k次免费机会的前提下 求最短路

code:

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f

using namespace std;
typedef pair<int,int> PII;

const int N=5e6+10;
int head[N],w[N],e[N],ne[N]; 
int dis[N],st[N];//dis 记录每个点到1最短距离   st记录每个点是否在队列中 
int n,m,cnt,k;

void add(int u,int v,int val){//链式前向星加边 
	e[cnt]=v,w[cnt]=val,ne[cnt]=head[u],head[u]=cnt++;
}

void dijkstra(int u){
	memset(dis,INF,sizeof(dis));
	dis[u]=0;
	priority_queue<PII,vector<PII>,greater<PII> > heap;
	heap.push({0,u});
	while(heap.size()){
		auto t=heap.top();
		heap.pop();
		int ver=t.second,distance=t.first;
		if(st[ver]) continue;
		st[ver]=1;
		for(int i=head[ver];i!=-1;i=ne[i]){
			int v=e[i];
			if(dis[v]>distance+w[i]){
				dis[v]=distance+w[i];
				heap.push({dis[v],v});
			}
		}
	}
}
int main()
{
	memset(head,-1,sizeof(head));
	int u,v;
	cin>>n>>m>>k;
	cin>>u>>v;
	int a ,b,c;
	while(m--){
		cin>>a>>b>>c;
		for(int i=0;i<=k;i++){
			add(a+i*n,b+i*n,c);
			add(b+i*n,a+i*n,c);
			if(i!=k){
				add(a+i*n,b+(i+1)*n,0);//俩个分身之间权值为0 
				add(b+i*n,a+(i+1)*n,0); 
			}
		}
	}
	dijkstra(u);
	int ans=INF;
	for(int i=0;i<=k;i++){//因为k次机会不一定都要使用,取个最小的就行了 
		ans=min(ans,dis[v+i*n]);
	}
	cout<<ans<<endl;
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值