典型的求k短路径的问题,有很多种算法,暂时试了试Dijkstra+A*算法
来源:互联网 发布:js改变body的display 编辑:程序博客网 时间:2024/05/24 16:17
poj2449 Remmarguts' Date
分类: POJ解题报告 k短路径 A*2012-05-16 21:20 86人阅读 评论(0) 收藏 举报
date算法structc++c
典型的求k短路径的问题,有很多种算法,暂时试了试Dijkstra+A*算法
k短路径的相关问题看这里,尽管已经是2007年的文章了,但作者真的写得非常详细和全面。
下面是一个简化的算法流程。
- /*
- * k短路径 Dijkstra+A*算法
- * 算法流程:
- * 1.将有向图的边反向后,Dijkstra求出任意节点到终点的最短路径 dis[i]
- * 2.优先队列
- * struct
- * {
- * int v,l,d;
- * }priority_queue[10000];
- * v:结点编号
- * l:源点到v的距离
- * d:源点经过v的到终点的某一条路径的长度
- * 优先队列以l为权值排序
- * 3.v = s,l = 0,d = 0; 入队
- * 每次从优先队列中取出并去除l最小的结点
- * 遍历结点v的所有后继,计算d,l并入队,不判断v的后继结点是否在队列中
- for(i=head[k];i;i=edge[i].next)
- {
- q[++len].v = edge[i].v;
- q[len].d = dis[edge[i].v]+edge[i].d+q[l].l;
- q[len].l = q[l].l+edge[i].d;
- inq[len] = true;
- sum++;
- }
- * 4.第k次取出终点结点t,d即为第k短路径
- * 可能出现同一长度的不同路径,都会被分别找出
- * */
- /*
- * poj2449 AC
- * k短路径 Dijkstra+A*算法 266ms
- * 第一次用STL,还不是很熟悉,以前都是手写二叉堆的。
- * Dijkstra开始写错了,导致TLE,一天不写手生。
- * 题目要注意,当终点和起点相同时,最短路径不是0,必须走一圈回来。
- * */
- #include<stdio.h>
- #include<memory.h>
- #include<queue>
- #include<fstream>
- #include<vector>
- using namespace std;
- #define INF 100000000
- struct EDGE
- {
- int v,t;
- long next;
- }edge[100005],e[100005];
- typedef struct
- {
- long len,d;
- int v;
- }NODE;
- struct cmp
- {
- bool operator()(const NODE &t1,const NODE &t2)
- {
- return t1.d>t2.d;
- }
- };
- long head[1005],h[1005];
- long n,m,tot,tot1;
- int a,b,c;
- long dis[1005];
- void Dijkstra()
- {
- bool vis[1005];
- NODE node,tmp;
- priority_queue<NODE,vector<NODE>,cmp> queue;
- long i,j;
- for(i=1;i<=n;i++)
- {
- vis[i] = false;
- dis[i] = INF;
- }
- dis[b] = 0;
- node.d= 0,node.v = b;
- queue.push(node);
- for(i=1;i<=n;i++)
- {
- node = queue.top();
- queue.pop();
- vis[node.v] = true;
- for(j=h[node.v];j;j=e[j].next)
- if(!vis[e[j].v] && dis[e[j].v]>dis[node.v]+e[j].t)
- {
- dis[e[j].v] = dis[node.v]+e[j].t;
- tmp.v = e[j].v;
- tmp.d= dis[e[j].v];
- queue.push(tmp);
- }
- }
- while(!queue.empty())
- queue.pop();
- return;
- }
- long a_star()
- {
- NODE node,tmp;
- long i,num = 0;
- priority_queue<NODE,vector<NODE>,cmp> queue;
- node.len = 0,node.d = 0,node.v = a;
- queue.push(node);
- while(!queue.empty())
- {
- node = queue.top();
- queue.pop();
- if(node.v==b)
- {
- num++;
- if(num==c) return node.d;
- }
- for(i=head[node.v];i;i=edge[i].next)
- {
- tmp.v = edge[i].v;
- tmp.d = node.len+edge[i].t+dis[edge[i].v];
- tmp.len = node.len+edge[i].t;
- queue.push(tmp);
- }
- }
- return -1;
- }
- int main()
- {
- // FILE* fin;
- // fin = fopen("d.in","r");
- scanf("%ld%ld",&n,&m);
- // fscanf(fin,"%ld%ld",&n,&m);
- int i,j,k,t;
- memset(head,0,sizeof(head));
- memset(h,0,sizeof(h));
- tot = tot1 = 0;
- for(i=1;i<=m;i++)
- {
- scanf("%d%d%d",&j,&k,&t);
- // fscanf(fin,"%d%d%d",&j,&k,&t);
- edge[++tot].v = k,edge[tot].t = t,edge[tot].next = head[j],head[j] = tot;
- e[++tot1].v = j,e[tot1].t = t,e[tot1].next = h[k],h[k] = tot1;
- }
- scanf("%d%d%d",&a,&b,&c);
- // fscanf(fin,"%d%d%d",&a,&b,&c);
- if(a==b) c++;
- Dijkstra();
- long ans;
- ans = a_star();
- printf("%ld\n",ans);
- return 0;
- }
- 典型的求k短路径的问题,有很多种算法,暂时试了试Dijkstra+A*算法
- 迪杰斯特拉(Dijkstra)算法求图的最短路径
- dijkstra算法--求两点之的最短路径
- 图论-有向带权图的最短路径(Dijkstra)算法
- 有向加权图的最短路径算法-Dijkstra
- 最短路径问题的Dijkstra和SPFA算法总结
- Dijkstra算法的最短路径实现
- 图的最短路径dijkstra算法
- Dijkstra 算法求非负权图的最短路径
- dijkstra最短路径算法的实现
- 最短路径的Dijkstra算法
- Dijkstra最短路径算法的优化
- Dijkstra算法--图的最短路径
- 对于前K短路径问题 和 A*算法 的一些小小总结
- 对于 前K短路径问题 和 A*算法 的一些小小总结
- 对于 前K短路径问题 和 A*算法 的一些小小总结
- 最短路径算法Dijkstra和A*
- 图的最短路径算法Dijkstra算法
- 学习OpenCV——Surf(特征点篇)&flann
- 7月1日
- 用profile协助程序性能优化
- iOS - Xcode 打包 ipa 包:
- 计算机网络1
- 典型的求k短路径的问题,有很多种算法,暂时试了试Dijkstra+A*算法
- 动态规划(5)字符串相似度算法
- Java excel 操作
- POJ 1426 Find The Multiple
- 保护眼睛的颜色的各种色值,强力推荐!
- Build openssl with just RSA and AES
- 黑马程序员--java集合TreeSet
- 对象克隆-深复制-浅复制
- 图之prim算法