A*模板
来源:互联网 发布:淘宝买游戏账号被找回 编辑:程序博客网 时间:2024/06/06 03:32
求第k短路。
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<queue>using namespace std;const int INF = 1e9+7;int n,m,ts,te,k,tot1,tot2,ru,rv,rw;int first1[100010],nxt1[100010],first2[100010],nxt2[100010],dis[100010];bool used[100010];struct edge{ int u,v,w;}l1[100010],l2[100010];struct st{ int num,d; bool operator < (st a)const { return d>a.d; }}p1[100010];priority_queue<st>q2;struct heap{ int g,h,num; bool operator < (heap a)const { return (g+h)>(a.g+a.h); }}p2[100010];priority_queue<heap>q1;void build_1(int f,int t,int c){ l1[++tot1]=(edge){f,t,c}; nxt1[tot1]=first1[f]; first1[f]=tot1;}void build_2(int f,int t,int c){ l2[++tot2]=(edge){f,t,c}; nxt2[tot2]=first2[f]; first2[f]=tot2;}void geth(){ for(int i=1;i<=n;i++) dis[i]=INF; dis[te]=0; q2.push((st){te,0}); while(!q2.empty()) { st h=q2.top(); q2.pop(); if(used[h.num]==1) continue; used[h.num]=1; for(int i=first2[h.num];i!=-1;i=nxt2[i]) { int x=l2[i].v; if(dis[x]>dis[h.num]+l2[i].w) { dis[x]=dis[h.num]+l2[i].w; q2.push((st){x,dis[x]}); } } }}void Astar(){ geth(); q1.push((heap){0,dis[ts],ts}); while(!q1.empty()) { heap h=q1.top(); q1.pop(); if(h.num==te) { tot1++; if(tot1>=k) { printf("%d",h.g); return; } } for(int i=first1[h.num];i!=-1;i=nxt1[i]) { int x=l1[i].v; q1.push((heap){h.g+l1[i].w,dis[x],x}); } } printf("-1");}int main(){ memset(first2,-1,sizeof(first2)); memset(first1,-1,sizeof(first1)); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d%d",&ru,&rv,&rw); build_1(ru,rv,rw); build_2(rv,ru,rw); } scanf("%d%d%d",&ts,&te,&k); if(ts==te) k++; tot1=0; Astar(); return 0;}
注意估价函数设置,对于求第k短路而言,估价函数的影响使得Dijkstra过程中只会依次严格经过第1,2…k短路上的边到达终点。
求第k短路也可以使用Dijkstra,第k次找到终点的路径即为由起点到终点的第k短路。
代码
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<queue>using namespace std;typedef long long ll;int n,m,ts,te,k,ru,rv,rw,tot;int first[100010],nxt[100010],cnt[100010];bool flag;ll ans;struct edge{ int u,v,w;}l[100010];struct st{ int num; ll d;}p;bool operator < (st a,st b){ return a.d>b.d;}priority_queue<st>q;void build(int f,int t,int c){ l[++tot]=(edge){f,t,c}; nxt[tot]=first[f]; first[f]=tot;}void Dijkstra(){ q.push((st){ts,0}); while(!q.empty()) { st h=q.top(); q.pop(); if(cnt[h.num]>=k)//十分重要的剪枝 continue; cnt[h.num]++; if(h.num==te&&cnt[h.num]==k) { flag=1; ans=h.d; break; } for(int i=first[h.num];i!=-1;i=nxt[i]) { int x=l[i].v; q.push((st){x,h.d+l[i].w}); } }}int main(){ memset(first,-1,sizeof(first)); scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d%d",&ru,&rv,&rw); build(ru,rv,rw); } scanf("%d%d%d",&ts,&te,&k); tot=0; Dijkstra(); if(flag) printf("%I64d",ans); else printf("-1"); return 0;}
阅读全文
0 0
- A*模板
- (BFS模板)A计划
- A*启发式搜索 模板
- A*启发式搜索模板
- 模板-高精度A+B,A-B
- a^b%c问题 ---模板
- 大数a^b%n模板
- 【HDU1698】【模板】Just a Hook
- a difficult problem FWT 模板
- poj 1459 EK 模板A题
- USTC1046 A * B Problem 高精度乘法模板
- 567Risk---------模板题1A
- 求 a^b mod mod 的模板
- 【矩阵模板】【hdu 1575】Tr A
- [HDU1402] A * B Problem Plus && FFT模板
- 扩展gcd模板,a^x=b。
- [HDU1402]A * B Problem Plus && FFT模板
- A - Tree Recovery(先序中序求后序的模板)
- 矩阵乘 [Shoi2013]超级跳马
- 【51nod】1461 稳定桌 扫描线+线段树
- 洛谷 1280 尼克的任务
- Samba服务器搭建
- BZOJ1812 RIV 树形dp
- A*模板
- 007 矩阵的秩定义、秩求法、秩的性质
- Win10-句柄异常的多,多达300万解决方式
- 表单验证-从js原生代码到Jquery validate
- [BZOJ1034]泡泡堂 贪心
- JEESZ分布式框架安装和使用
- 【第04章】【传输】
- KafKa+Zookeeper+Flume部署脚本
- [分块 DP] 51Nod1259 整数划分 V2