迪杰斯特拉+A*算法
f(i) = g(i) + h(i)
优先队列每次让队列中f最小的值出队
若t第n次从队列出来,则为从s到t的第K条最短路径
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
struct Edge
{
int to;
int w;
int next;
};
Edge edge[100100];
Edge edge2[100100];
struct Node
{
int f;
int g;
int v;
bool operator < (const Node &b) const
{
return b.f < f;
}
};
int head[1005];
int head2[1005];
int dis[1005];
int visit[1005];
int cnt[1005];
const int MAX = 0x7fffffff;
void dijkstra(int start,int n)
{
dis[start] = 0;
for(int i = 1;i<=n;i++)
{
int temp = MAX;
int record = 0;
for(int j = 1;j<=n;j++)
{
if(visit[j]==false&&dis[j]<temp)
{
temp = dis[j];
record = j;
}
}
visit[record] = true;
for(int i = head2[record];i!=0;i=edge2[i].next)
{
int k = edge2[i].to;
int w = edge2[i].w;
if(visit[k]==false&&dis[k]>dis[record]+w)
{
dis[k] = dis[record]+w;
}
}
}
}
int AStar(int start,int end,int k)
{
priority_queue <Node> que;
if(dis[start]==MAX)
{
return -1;
}
Node t;
t.f = dis[start];t.g = 0;t.v = start;
que.push(t);
while(!que.empty())
{
Node t = que.top();
que.pop();
cnt[t.v]++;
if(cnt[end]==k)
return t.f;
for(int i = head[t.v];i!=0;i=edge[i].next)
{
Node temp;
temp.v = edge[i].to;
temp.g = t.g+edge[i].w;
temp.f = temp.g+dis[temp.v];
que.push(temp);
}
}
return -1;
}
int main()
{
int n,m,u,v,w;
while(scanf("%d %d",&n,&m)!=EOF)
{
for(int i = 0;i<1005;i++)
{
head[i] = head2[i] = cnt[i]=0;
visit[i] = false;
dis[i] = MAX;
}
for(int i = 1;i<=m;i++)
{
scanf("%d %d %d",&u,&v,&w);
edge[i].to = v;
edge[i].w = w;
edge[i].next = head[u];
head[u] = i;
edge2[i].to = u;
edge2[i].w = w;
edge2[i].next = head2[v];
head2[v] = i;
}
scanf("%d %d %d",&u,&v,&w);
dijkstra(v,n);
if(u==v)
w++;
int ans = AStar(u,v,w);
printf("%d\n",ans);
}
return 0;
}