【 BZOJ 2763 】【 飞行路线 】【 分层图 最短路 模型 】

推荐博客 (详细) : 本题 + 分层图最短路 讲解

只是不明白,为什么手写队列 凉凉了?

于是乎,稍后补上 双端队列 Spfa

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#define LL long long
#define inff 0x7f7f7f7f7f
using namespace std;

inline int wread(){
	char c(getchar ());int wans=0,flag=1;
	while (c<'0' || c>'9'){if (c=='-') flag=-1; c=getchar();}
	while (c>='0' && c<='9'){wans=wans*10+c-'0';c=getchar ();}
	return wans*=flag;
} 

inline LL ll_wread(){
	char c(getchar ());LL wans=0,flag=1;
	while (c<'0' || c>'9'){if (c=='-') flag=-1; c=getchar();}
	while (c>='0' && c<='9'){wans=wans*10+c-'0';c=getchar ();}
	return wans*=flag;
} 

int n,m,k;
int S,T;
bool ins[10006][11];
struct node2{int poit,num;};
int K,hed[10006];
struct node{int v,nxt;LL w;}e[100006];
void ad (int u,int v,LL w){e[++K].v=v;e[K].w=w;e[K].nxt=hed[u];hed[u]=K;}
LL G[10006][12];
queue<node2> que;
void Spfa (){
	for (int i(0);i<=n;++i){
		for (int j(0);j<=k;++j){
			G[i][j]=inff;
		}
	}
	que.push((node2){S,0});
	G[S][0] = 0;
	
	while (!que.empty()){
		node2 h=que.front();
		int x=h.poit; int num_lu=h.num;
		ins[ x ][ num_lu ]=false;
		que.pop();
		for (int i=hed[x];i;i=e[i].nxt){
			int v(e[i].v);
			
			if ( num_lu<=k && G[v][ num_lu ] > G[x][ num_lu ] + e[i].w ){
				
				G[v][ num_lu ] = G[x][ num_lu ] + e[i].w;
				if ( !ins[v][ num_lu ] ) que.push((node2) {v,num_lu}) ;ins[v][ num_lu ]=true;
			}
			if ( num_lu<k && G[v][num_lu+1] > G[x][ num_lu ]){
				G[v][ num_lu+1 ] = G[x][ num_lu ];
				if ( !ins[v][ num_lu+1 ] ) que.push((node2){v,num_lu+1}) ;ins[v][ num_lu+1 ]=true;
			}
		}
	}
	
	printf("%lld\n",G[ T ][ k ]);
	
}
int main (){
//	
	
	n=wread(),m=wread(),k=wread();
	S=wread(),T=wread();
	S++; T++;
	for (int i(1);i<=m;++i){
		int u(wread()),v(wread()); LL w(ll_wread());
		u++; v++;
		ad (u,v,w); ad (v,u,w);
	}
	
	Spfa();
	
	return 0;
}

双端队列:如果对一个点更新,当前点比我队首的元素值还小,那么我就把这个点加在队首,否则加在队尾。

因此,利用双端队列 优化 Spfa

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#define LL long long
#define inff 0x7f7f7f7f7f
using namespace std;
 
inline int wread(){
	char c(getchar ());int wans=0,flag=1;
	while (c<'0' || c>'9'){if (c=='-') flag=-1; c=getchar();}
	while (c>='0' && c<='9'){wans=wans*10+c-'0';c=getchar ();}
	return wans*=flag;
} 
 
inline LL ll_wread(){
	char c(getchar ());LL wans=0,flag=1;
	while (c<'0' || c>'9'){if (c=='-') flag=-1; c=getchar();}
	while (c>='0' && c<='9'){wans=wans*10+c-'0';c=getchar ();}
	return wans*=flag;
} 
 
int n,m,k;
int S,T;
bool ins[10006][11];
struct node2{int poit,num;};
int K,hed[10006];
struct node{int v,nxt;LL w;}e[100006];
void ad (int u,int v,LL w){e[++K].v=v;e[K].w=w;e[K].nxt=hed[u];hed[u]=K;}
LL G[10006][12];
deque<node2> que;
void Spfa (){
	for (int i(0);i<=n;++i){
		for (int j(0);j<=k;++j){
			G[i][j]=inff;
		}
	}
	que.push_front((node2){S,0});
	G[S][0] = 0;
	
	while (!que.empty()){
		node2 h=que.front();
		int x=h.poit; int num_lu=h.num;
		ins[ x ][ num_lu ]=false;
		que.pop_front();
		for (int i=hed[x];i;i=e[i].nxt){
			int v(e[i].v);
			
			if ( num_lu<=k && G[v][ num_lu ] > G[x][ num_lu ] + e[i].w ){
				
				G[v][ num_lu ] = G[x][ num_lu ] + e[i].w;
				if ( !ins[v][ num_lu ] ) {
					ins[v][ num_lu ]=true;
					node2 f;bool D=false;
					if (!que.empty()){
						f=que.front();
						D=true;
					}
					if (D && G[f.poit][f.num]>G[v][num_lu])
						que.push_front((node2){v,num_lu});
					else que.push_back((node2){v,num_lu})	;
				}
			}
			if ( num_lu<k && G[v][num_lu+1] > G[x][ num_lu ]){
				G[v][ num_lu+1 ] = G[x][ num_lu ];
				if ( !ins[v][ num_lu+1 ] ) {
					ins[v][ num_lu+1 ]=true;
					node2 F;bool D=false;
					if (!que.empty()){
						D=true;
						F=que.front();
					}
					if ( D && G[F.poit][F.num] > G[v][num_lu+1])
						que.push_front((node2){v,num_lu+1});
					else que.push_back((node2){v,num_lu+1});
				}
			}
		}
	}
	
	printf("%lld\n",G[ T ][ k ]);
	
}
int main (){
//	
	
	n=wread(),m=wread(),k=wread();
	S=wread(),T=wread();
	S++; T++;
	for (int i(1);i<=m;++i){
		int u(wread()),v(wread()); LL w(ll_wread());
		u++; v++;
		ad (u,v,w); ad (v,u,w);
	}
	
	Spfa();
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/violinlove/article/details/81456194