-
Two Paths
- HDU - 6181
- 题意:很直接就是求次短路。
- 思路:简单谈一谈我所了解的A*,核心为估价函数 f=g+h,f为所求距离,g为从起点bfs到次的距离。
- h为估计的从此处到终点的距离,说是估计不过是预处理而已,堆优化dijkstra,预处理出dis[]数组
- 里面存储的是每个点到终点n的距离。然后就是A*算法了,打一个变量记录第几次访问到终点
- 当访问终点次数达到K时输出f即可。g就根据bfs顺序不断更新,h就是预处理出来的dis这样A*算法就可以解决第K短路问题了。
-
#include <bits/stdc++.h> using namespace std; const long long inf=1e15; struct node { long long to,w,next; } e[200005]; struct nodee { long long u,w; bool operator < (const nodee &b)const { return b.w<w; } }; struct nodeee { long long u,f,h; bool operator < (const nodeee &b)const { if(b.h==h)return f>b.f; return h>b.h; } }; long long n,m; long long head[100005],cnt=1,vis[100005]; long long dis[100005]; void add(long long u,long long v,long long w) { e[cnt].to=v; e[cnt].w=w; e[cnt].next=head[u]; head[u]=cnt++; } void d() { for(long long i=1; i<=n; i++) { dis[i]=inf; vis[i]=0; } priority_queue<nodee>q; q.push(nodee{n,0}); dis[n]=0; while(!q.empty()) { long long x=(q.top()).u; q.pop(); if(vis[x])continue; vis[x]=1; for(long long i=head[x]; i!=-1; i=e[i].next) { long long to=e[i].to; long long w=e[i].w; if(!vis[to]&&dis[to]>dis[x]+w) { dis[to]=dis[x]+w; q.push(nodee{to,dis[to]}); } } } } long long bfs() { priority_queue<nodeee>q; q.push(nodeee{1,0,0}); long long int cnt=0; while(!q.empty()) { nodeee x=q.top(); q.pop(); if(x.u==n)cnt++; if(cnt==2)return x.f; for(int i=head[x.u]; i!=-1; i=e[i].next) { long long to=e[i].to; long long w=e[i].w; long long f=w+x.f; long long h=f+dis[to]; q.push(nodeee{to,f,h}); } } } int main() { int t; scanf("%d",&t); while(t--) { memset(head,-1,sizeof(head)); cnt=1; scanf("%lld %lld",&n,&m); long long u,v,w; for(long long i=1; i<=m; i++) { scanf("%lld %lld %lld",&u,&v,&w); add(u,v,w); add(v,u,w); } d(); long long ans=bfs(); printf("%lld\n",ans); } return 0; }