#include <queue>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <stdio.h>
using namespace std;
#define ll long long
#define mem(a, b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define DBG printf("this is a input\n")
#define fi first
#define se second
#define mk(a, b) make_pair(a,b)
#define p_queue priority_queue
struct e{
int to , next , w;
}edge[200005],f_edge[200005];
int n , m, s, e, k;
p_queue <pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > >q;
int vis[1005] , dis[1005], cnt1 = 0, cnt2 = 0, head1[1005], head2[1005];
struct node
{
int v ;
int cost;
bool operator <(const node&another)const{
return cost + dis[v] > another.cost + dis[another.v];
}
node(int a,int c):v(a),cost(c) {}
};
p_queue <node> aq;
void add1(int f, int t, int w)
{
edge[cnt1].to = t;
edge[cnt1].w = w;
edge[cnt1].next = head1[f];
head1[f] = cnt1 ++;
}
void add2(int f, int t, int w)
{
f_edge[cnt2].to = t;
f_edge[cnt2].w = w;
f_edge[cnt2].next = head2[f];
head2[f] = cnt2 ++;
}
void dijsktra()
{
pair<int,int> pa;
pa.first = 0;
pa.second = e;
dis[e] = 0;
q.push(pa);
while(!q.empty())
{
pair<int,int> no = q.top();
q.pop();
if(vis[no.second]) continue;
vis[no.second] = 1;
for(int i = head2[no.second] ; i != -1 ; i = f_edge[i].next)
{
int v = f_edge[i].to ,w = f_edge[i].w;
if(dis[no.second] + w < dis[v] && !vis[v])
{
dis[v] = dis[no.second] + w;
q.push(mk(dis[v],v));
}
}
}
}
int Astar()
{
aq.push(node(s,0));
while(!aq.empty())
{
node no = aq.top();
aq.pop();
if(no.v == e)
{
k--;
if(k == 0)
return no.cost;
}
for(int i = head1[no.v] ; i != -1 ; i = edge[i].next)
aq.push(node(edge[i].to,no.cost+edge[i].w));
}
return -1;
}
int main(void) {
mem(dis,INF);
mem(head1,-1);
mem(head2,-1);
mem(vis,0);
scanf("%d %d",&n, &m);
for(int i = 1 ; i <= m ; i ++)
{
int u ,v , w;
scanf("%d %d %d",&u, &v, &w);
add1(u,v,w);
add2(v,u,w);
}
scanf("%d %d %d",&s, &e, &k);
if(s == e)
k ++;
dijsktra(); //先求出所有点到终点的距离(反向建图,终点作为起点跑dij即可)
printf("%d\n",Astar());//A*算法用于求出k短路
}
k短路求解步骤:
1.建立反向图,并求出任意点到终点的最短距离(dij算法)
2.利用A*进行搜索 启发式函数:
对于A*,估价函数=当前值+当前位置到终点的距离,即f(V)=g(V)+h(V),每次扩展估价函数值最小的一个;
对于K短路算法来说:
g(V)为当前从S到V所走的路径的长度(广搜变量记录);
h(V)为点V到的最短路的长度(第一步已经求出);
837

被折叠的 条评论
为什么被折叠?



