【dijkstra + 优先队列 && bfs && A*】POJ
来源:互联网 发布:网络语言膜法什么意思 编辑:程序博客网 时间:2024/06/01 07:27
Problem Description
裸的第k短路模板题。给你n个点,m条边,每条边u, v, w代表u - v 的距离是w。给你起点终点,让你求起点到终点的第k短路。
思路:
A* :设s是起点,t是终点。f(p) = g(p) + h(p); g(p)为当前从s到p所走的路径长度,h(p)为从点p到t的最短路的长度; 这样bfs的时候 因为我们想求最短路,所以每次出来最小的g,如果g相等出来最小的h。h[]可以根据反向建图,求终点到起点的最短路求出。
#include<cstdio>#include<cstring>#include<queue>using namespace std;#define inf 0x3f3f3f3fstruct node{ int to, w, next; bool operator < (const node &b) const { if(w == b.w) return to > b.to; else return w > b.w; }};node edge[100015];int head[1015];node edge1[100015];int head1[1015], n;int h[1015], k;struct node1{ int to; int g, f;//g为当前所走的路径长度 f = g + h bool operator < (const node1 &b) const {//最小堆 if(f == b.f) return g > b.g; else return f > b.f; }};void dij(int u, int v)//dijkstra + 优先队列(最小堆){ memset(h, inf, sizeof(h));//初始化h[] h[u] = 0; priority_queue<node> q; q.push((node){u, h[u]}); while(!q.empty()) { node t = q.top(); q.pop(); for(int i = head1[t.to]; ~i; i = edge1[i].next) { int to = edge1[i].to, w = edge1[i].w; if(h[to] > h[t.to] + w) { h[to] = h[t.to] + w; q.push((node){to, h[to]}); } } }}int bfs(int u, int v){ int cnt = 0; if(h[u] == inf) return -1;//无法到达输出-1 if(u == v) k++;//如果回到自身 k++因为一会儿出栈的时候cnt++为了抵消掉 priority_queue<node1> q; q.push((node1){u, 0, h[u]}); while(!q.empty()) { node1 t = q.top(); q.pop(); if(t.to == v)//每到达终点一次cnt++; { cnt++; } if(cnt == k)//如果达到第k次返回 距离 { return t.g; } for(int i = head[t.to]; ~i; i = edge[i].next) { int to = edge[i].to, g = edge[i].w + t.g; int f = g + h[to];//附近的点进入队列 q.push((node1){to, g, f}); } } return -1;//找不到第k短路}void add(int u, int v, int w, node edg[], int hea[], int &cnt)//前向星存图{ edg[cnt].to = v; edg[cnt].w = w; edg[cnt].next = hea[u]; hea[u] = cnt++;}int main(){ int m, i, u, v, w; while(~scanf("%d %d", &n, &m)) { int cnt = 0, cnt1 = 0; memset(head, -1, sizeof(head)); memset(head1, -1, sizeof(head1)); for(i = 0; i < m; i++) { scanf("%d %d %d", &u, &v, &w); add(u, v, w, edge, head, cnt); add(v, u, w, edge1, head1, cnt1);//反向建图 } scanf("%d %d %d", &u, &v, &k); dij(v, u);//求终点到各个点的最短路 printf("%d\n", bfs(u, v)); } return 0;}
阅读全文
0 0
- 【dijkstra + 优先队列 && bfs && A*】POJ
- 【bfs优先队列】POJ 3635
- 【bfs优先队列】POJ 2312
- poj 2021 优先队列bfs
- poj 3635(bfs+优先队列)
- Poj 2312 BFS+优先队列
- POJ 2312(BFS+优先队列)
- POJ 3635 优先队列BFS
- poj 1724(Dijkstra+优先队列)
- poj 1724~ROADS(dijkstra+优先队列)
- poj 2387(Dijkstra优先队列优化)
- POJ 3635 基于优先队列的BFS
- POJ 2312 Battle City 优先队列+BFS
- 【bfs优先队列/floodfill】POJ 2227
- POJ 1847 Tram 优先队列+bfs
- POJ 1724 ROADS (优先队列+BFS)
- 【BFS+优先队列】Battle City(poj-2312)
- POJ 2049 Finding Nemo (bfs+优先队列)
- JSONObject、JSONArray
- Git分支管理的策略梳理
- 教大家如何区分屏蔽数据线的好坏
- 微信小程序笔记心得
- selenium3.x 踏坑记
- 【dijkstra + 优先队列 && bfs && A*】POJ
- somnic各应用下载目录
- web.xml 中的listener、 filter、servlet 加载顺序及其详解
- LA 3720 Highway n x m的点阵 有多少条直线穿过至少2个点
- POJ 1012 Joseph
- Max Sum Plus Plus HDU
- mysql索引的长度问题
- 【VS】控制台程序,更改系统默认图标。
- 微信小程序开发(5)-新闻页之滚动制作(scroll-view)组件的使用