推荐博客 (详细) : 本题 + 分层图最短路 讲解
只是不明白,为什么手写队列 凉凉了?
于是乎,稍后补上 双端队列 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;
}