P4568 [JLOI2011]飞行路线 (分层最短路&模板)

题目传送门

思路:板子题,具体看代码。

AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N=5e6+5;
struct edge{
	int to,nt,w;
}e[N];
struct node{
	int d,id;
	bool operator<(const node&a)const{
		return d>a.d;
	}
}now;
int cnt=1,n,m,k,st,ed,d[N],h[N],vis[N];
void add(int u,int v,int w){
	e[cnt].to=v;
	e[cnt].w=w;
	e[cnt].nt=h[u];
	h[u]=cnt++;
}
void dij(int st){ //dijkstra 板子 
	priority_queue<node>q;
	memset(d,0x3f,sizeof d);
	d[st]=0,q.push({d[st],st});
	while(q.size()){
		int u=q.top().id;q.pop();
		if(vis[u]) continue;
		vis[u]=1;
		for(int i=h[u];i;i=e[i].nt){
			int v=e[i].to,w=e[i].w;
			if(!vis[v]&&d[v]>d[u]+w) 
			 	d[v]=d[u]+w,q.push({d[v],v});
		}
	} 
}
int main(){
	scanf("%d%d%d%d%d",&n,&m,&k,&st,&ed);
	for(int i=1,u,v,w;i<=m;i++){
		scanf("%d%d%d",&u,&v,&w);
		for(int j=0;j<=k;j++){
			add(u+j*n,v+j*n,w);
			add(v+j*n,u+j*n,w);
			if(j!=k){ //对下一层建立连接.(除了第k层 因为第k层是最后一层了) 
				add(u+j*n,v+(j+1)*n,0);
				add(v+j*n,u+(j+1)*n,0);
			}
		}
	}
	dij(st);
	int ans=0x3f3f3f3f;
	for(int i=0;i<=k;i++)
		ans=min(ans,d[ed+i*n]);//取所有层的终点的最小值. 
	printf("%d\n",ans);
	return 0;
}