您的位置:首页 > 其它

典型的求k短路径的问题,有很多种算法,暂时试了试Dijkstra+A*算法

2013-07-01 21:27 281 查看


poj2449 Remmarguts' Date

分类: POJ解题报告 k短路径 A*2012-05-16
21: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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: