题目地址


注意点:

  • 起点和终点相同时,k需要提前++.
  • Node内的比较函数应当使用:当前费用+预估费用.

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int MAXN=3e3,MAXM=3e5;
struct Edge_First{//反向图 
	int from,to,nxt,w;
}e_First[MAXM];
int head_First[MAXN],edgeCnt_First=1;
void addEdge_First(int u,int v,int w){
	e_First[++edgeCnt_First].from=u;
	e_First[edgeCnt_First].to=v;
	e_First[edgeCnt_First].w=w;
	e_First[edgeCnt_First].nxt=head_First[u];
	head_First[u]=edgeCnt_First;
}
int s,t,k;//起点 终点 第k短路 
struct Node_First{
	int v,dis;
	bool operator <(Node_First another)const{
		return dis>another.dis;
	}
};
int f[MAXN];//估价函数 
void dijkstra(){
	memset(f,0x3f,sizeof(f));
	priority_queue<Node_First> q;
	q.push(Node_First{t,0});
	f[t]=0;
	while(!q.empty()){
		Node_First nowNode=q.top();
		q.pop();
		int nowU=nowNode.v;
		if(nowNode.dis!=f[nowU])continue;
		for(int i=head_First[nowU];i;i=e_First[i].nxt){
			int nowV=e_First[i].to;
			if(f[nowV]>f[nowU]+e_First[i].w){
				f[nowV]=f[nowU]+e_First[i].w;
				q.push(Node_First{nowV,f[nowV]});
			}
		}
	}
}
struct Edge{
	int from,to,w,nxt;
}e[MAXM];
int head[MAXN],edgeCnt=1;
void addEdge(int u,int v,int w){
	e[++edgeCnt].from=u;
	e[edgeCnt].to=v;
	e[edgeCnt].w=w;
	e[edgeCnt].nxt=head[u];
	head[u]=edgeCnt;
}
struct Node{
	int v,f,g; 
	bool operator <(Node another)const{
		return f+g>another.f+another.g;
	}
};
int updateTime[MAXN];
int ans;
bool Astar(){
	priority_queue<Node> q;
	q.push(Node{s,f[s],0});
	while(!q.empty()){
		Node nowNode=q.top();
		q.pop();
		int nowU=nowNode.v;
		updateTime[nowU]++;
		if(nowU==t&&updateTime[nowU]==k){
			ans=nowNode.g;
			return 1;
		}
		for(int i=head[nowU];i;i=e[i].nxt){
			int nowV=e[i].to;
			q.push(Node{nowV,f[nowV],nowNode.g+e[i].w});
		}
	}
	return 0;
}
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int a,b,l;
		scanf("%d%d%d",&a,&b,&l);
		addEdge_First(b,a,l);//反向边
		addEdge(a,b,l);//正向边 
	}
	scanf("%d%d%d",&s,&t,&k);
	if(s==t)k++;
	dijkstra();
	if(Astar()){
		cout<<ans<<endl;
	}else cout<<"-1"<<endl;
	return 0;
}