标签:sts hid view display real show nes bsp main
Input
Output
Sample Input
2 2 1 2 5 2 1 4 1 2 2
Sample Output
14
题意:n个点,m条边的有向图,每个点可以多次抵达,给出s、t、k,求从s到t的第k短路
思路:求最短路最常用的就是堆优化的dijkstra,那么很容易想到的一种写法:用dijkstra,当t第k次出现,那就是第k短路;但是如果有些状态当前值很小,但是未来值很大,优先队列就会先去扩展这个状态,
这样的情况多了,就会导致搜索量增大。
优先队列是以当前所走过的路程最小的为优先的,它并不知道该状态后面的情况,所有排序并不是很完美,这时候我们就可以想到为其加入评估函数(估计该状态后面所需的路程),并且评估值<=实际值。
这样我们使用优先队列是,将(该状态花费+评估值,节点)送入队列,取出时是总体评估最小,也就是不仅考虑了已走路程,顺便考虑了其后续可能路程,取出之后,花费-该点评估值==实际花费,然后扩展该状态,
将(状态实际花费+下个点评估值+该路径长度)送入队列
这样当t出项k次时出现的就是第k短路
因为 评估值<=实际值,所以状态花费+评估值 <= 状态花费+实际值 == s(总花费),所以最优值肯定会在次优值之前出栈,(虽然之前的优先队列也这样)而且因为评估了后续所需,所以不会出现前小后大的
非最优花费大量在队列前扩展,尽量让其直接将最优解排在队列前扩展,少扩展其他分支。
那么这个题的评估函数怎么求呢,因为我们是求到t的k短路,那么我们就把所有点到t的对短路当成评估函数,也就是以t为原点,求一遍最短路,刚好这个值可以反应未来变化的趋势和相对大小关系
注:该题当s==t时,0并不是第一条路
#include<iostream> #include<cstdio> #include<queue> #include<string.h> using namespace std; int n,m; typedef pair<int,int>p; struct E { int x,y,val; int next; E(int x=0,int y=0,int val=0,int next=-1):x(x),y(y),val(val),next(next){} }edge[100005]; int next[1005]; int cnt; E t_edge[100005]; int t_next[1005]; int t_cnt; int f[1005]; int ans[1005]; void add(int x,int y,int val) { edge[++cnt] = E(x,y,val,next[x]); next[x] = cnt; t_edge[++t_cnt] = E(y,x,val,t_next[y]); t_next[y] = t_cnt; } void get_f(int t) { memset(f,0x3f,sizeof(f)); priority_queue<p,vector<p>,greater<p> >que; while(!que.empty())que.pop(); que.push(p(0,t)); while(!que.empty()) { p tmp = que.top(); que.pop(); int now = tmp.second; int cost = tmp.first; if(f[now] != 0x3f3f3f3f)continue; f[now] = cost; for(int i=t_next[now];i!=-1;i=t_edge[i].next) { if(f[now] + t_edge[i].val < f[t_edge[i].y]) { que.push(p(f[now] + t_edge[i].val,t_edge[i].y)); } } } } int cal(int s,int t,int k) { priority_queue<p,vector<p>,greater<p> >que; while(!que.empty())que.pop(); que.push(p(f[s],s)); memset(ans,0x3f,sizeof(ans)); int cnt = 0; if(s == t)k++; while(!que.empty()) { p tmp = que.top(); que.pop(); int now = tmp.second; int cost = tmp.first - f[now]; if(now == t) { cnt++; if(cnt == k)return cost; } for(int i=next[now];i!=-1;i=edge[i].next) { que.push(p(cost+edge[i].val+f[edge[i].y],edge[i].y)); } } return -1; } int main() { scanf("%d%d",&n,&m); memset(next,-1,sizeof(next)); memset(t_next,-1,sizeof(t_next)); for(int i=1;i<=m;i++) { int u,v,k; scanf("%d%d%d",&u,&v,&k); add(u,v,k); } int s,t,k; scanf("%d%d%d",&s,&t,&k); get_f(t); printf("%d\n",cal(s,t,k)); }
Remmarguts' Date POJ - 2449 (A*搜索|k短路)
标签:sts hid view display real show nes bsp main
原文地址:https://www.cnblogs.com/iwannabe/p/10609823.html