a*算法就是在bfs扩展的时候优化了一下,对于一个点x,当前花费a,到终点花费h[x],那a+h[x]就可以视作它这个点的总花费,这就可以在bfs时优先遍历花费少的点
#include<algorithm>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;
#define ll long long
#include<stdio.h>
#define maxn 205000
#define mod 100003
vector<pair<int,int> >e[maxn];
vector<pair<int,int> >e1[maxn];
int h[maxn];
struct node
{
int d,id;
friend bool operator <(node a,node b)
{
return h[a.id]+a.d>h[b.id]+b.d;
}
};
priority_queue<node>q;
struct node1
{
int d,id;
friend bool operator <(node1 a,node1 b)
{
return a.d>b.d;
}
};
priority_queue<node1>q1;
int vis1[maxn];
void dijk(int st)
{
memset(h,0x3f,sizeof(h));
h[st]=0;
q1.push(node1{0,st});
while(!q1.empty())
{
int u=q1.top().id;
q1.pop();
//printf("u=%d\n",u);
if(vis1[u]==1) continue;
vis1[u]=1;
//printf("1111\n");
for(int i=0;i<e1[u].size();i++)
{
//printf("3333\n");
int v=e1[u][i].first,w=e1[u][i].second;
//printf("----\n");
//printf("v=%d\n",v);
if(h[u]+w<h[v])
{
h[v]=h[u]+w;
//printf(" v=%d\n",v);
if(vis1[v]==0)q1.push(node1{h[v],v});
}
}
}
//printf("222\n");
}
int ans[maxn];
void slove(int s,int t,int k)
{
int p=0;
q.push(node{0,s});
memset(ans,-1,sizeof(ans));
while(!q.empty()&&p<k)
{
int u=q.top().id,d=q.top().d;
q.pop();
//printf("u=%d d=%d\n",u,d);
if(u==t) ans[++p]=d;
for(int i=0;i<e[u].size();i++)
{
int v=e[u][i].first,w=e[u][i].second;
if(h[u]==h[maxn-1]) continue;
//if(v==t) ans[++p]=d+w;
//printf(" v=%d w=%d p=%d\n",v,w,p);
q.push(node{d+w,v});
}
}
printf("%d\n",ans[k]);
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
{
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
e[u].push_back({v,w});
e1[v].push_back({u,w});
}
int s,t,k;
scanf("%d %d %d",&s,&t,&k);
dijk(t);
if(s==t) k++;
//for(int i=1;i<=n;i++) printf("h[%d]=%d\n",i,h[i]);
slove(s,t,k);
}