典型的求k短路径的问题,有很多种算法,暂时试了试Dijkstra+A*算法
2013-07-01 21:27
281 查看
poj2449 Remmarguts' Date
分类: POJ解题报告 k短路径 A*2012-05-1621:20 86人阅读 评论(0) 收藏 举报
date算法structc++c
典型的求k短路径的问题,有很多种算法,暂时试了试Dijkstra+A*算法
k短路径的相关问题看这里,尽管已经是2007年的文章了,但作者真的写得非常详细和全面。
下面是一个简化的算法流程。
[cpp] view
plaincopy
/*
* 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短路径
* 可能出现同一长度的不同路径,都会被分别找出
* */
[cpp] view
plaincopy
/*
* 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;
}
相关文章推荐
- 最短路径问题---迪杰斯特拉(dijkstra)算法
- HDU3790 最短路径问题【Dijsktra算法】
- 群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法【附C#群蚁算法完整项目代码】
- 最短路径问题--Bellman-Ford最短路径算法
- 最大流问题:增广路径算法的比较
- 数据结构看书笔记(十)—— 求最短路径问题之--迪杰斯特拉(Dijkstra)算法和弗洛伊德(Floyd)算法
- 每周算法练习——用动态规划求解最短路径问题
- 最大流问题:增广路径算法的比较
- 关于经过若干指定节点最短路径问题的算法。
- 贪心算法之最短路径问题(Dijkstra算法)
- 物流配送路径优化问题分析与算法解读(一)
- 算法——算术表达式计算问题(堆栈典型应用)
- 最短路径问题 迪杰斯特拉(Dijkstra)算法
- [置顶]群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法【附C#群蚁算法完整项目代码】
- 算法java实现--贪心算法--单源最短路径问题--Dijkstra算法
- JAVA代码—算法基础:三角形最短路径问题
- 算法:C++实现动态规划中的几个典型问题
- Bellman-Ford算法之单源最短路径问题
- 九度 OJ 题目1008:最短路径问题 (Dijstra 算法)
- POJ-3984迷宫问题(典型BFS找最短路径)