poj 2449(A*+dijstra求k短路)
2012-08-30 23:23
260 查看
A*算法入门
A*算法是一种启发式的搜索,不是纯粹的盲目式搜索,A*算法中有个估价算法g(n),对于每个点而言,都有一个g(n)和h(n)来确定的f(n),实际上就是以f(n)为参考权值来确定搜索的方向,在这里,我们的h(n)表示的是从s点出发到n这个点现在走过的路径长度,而g(n)表示的是从n到e的最短长度的大小,那么就确定了搜索的优先性,这里的A*算法的估价函数g(n)是完美估价,搜索的方向一定是对的。
分析:
建图的时候建一个正向的一个反向的,反向的图利用dij求终点到每个点的最短路,即为搜索的估价函数。
注意的地方:
st==en 的时候必须k++ 因为题目要求必须走过路径。
详细见代码
A*算法是一种启发式的搜索,不是纯粹的盲目式搜索,A*算法中有个估价算法g(n),对于每个点而言,都有一个g(n)和h(n)来确定的f(n),实际上就是以f(n)为参考权值来确定搜索的方向,在这里,我们的h(n)表示的是从s点出发到n这个点现在走过的路径长度,而g(n)表示的是从n到e的最短长度的大小,那么就确定了搜索的优先性,这里的A*算法的估价函数g(n)是完美估价,搜索的方向一定是对的。
分析:
建图的时候建一个正向的一个反向的,反向的图利用dij求终点到每个点的最短路,即为搜索的估价函数。
注意的地方:
st==en 的时候必须k++ 因为题目要求必须走过路径。
详细见代码
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; #define inf 0x7ffffff #define MAXN 1010 #define MAXM 100005 struct Edge { int u;//反向图的终止边 int v;//终止点 int c;//边权值 int next;//下一个节点 int next1;//反向边下一个节点 Edge(){} Edge(int u,int v,int c):u(u),v(v),c(c){} }p[MAXM]; int head[MAXN];//链表头 int head1[MAXN];//反向 int e; //邻接表中边总数 int st,en,k;//起点,终点,第k短路 int n,m; int dis[MAXN];//dis[v]表示的是终点到v的距离,即估价函数g bool vis[MAXN]; struct pro { int v,c;//v是终点,c是起点到v的距离 pro(){} pro(int v,int c):v(v),c(c){} bool operator < (const pro& a) const { return c+dis[v] > a.c+dis[a.v];//最小值优先队列 } }; void clear()//初始化 { memset(head,-1,sizeof(head)); memset(head1,-1,sizeof(head1)); e=0; } void addEdge(int u,int v,int c)//加边 { p[e]=Edge(u,v,c); p[e].next1=head1[v];head1[v]=e; p[e].next=head[u];head[u]=e++; } priority_queue<pro> que; void dij(int src)//求估价函数 { memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) dis[i]=inf; dis[src]=0; while(!que.empty()) que.pop(); que.push(pro(src,0)); while(!que.empty()) { pro cur = que.top(); que.pop(); if(vis[cur.v]) continue; vis[cur.v]=1; for(int i=head1[cur.v];i+1;i=p[i].next1) { if(dis[p[i].u] > dis[cur.v] + p[i].c) { dis[p[i].u] = dis[cur.v] + p[i].c; que.push(pro(p[i].u,0)); } } } } int a_star(int src) { while(!que.empty()) que.pop(); que.push(pro(src,0)); while(!que.empty()) { pro cur = que.top(); que.pop(); if(cur.v==en) { if(k>1)//相当于求k次最短路 k--; else return cur.c; } for(int i=head[cur.v];i+1;i=p[i].next)//将所有与u相连接的点都加入队列 que.push(pro(p[i].v,cur.c+p[i].c)); } return -1; } int main() { int u,v,c; while(scanf("%d%d",&n,&m) != EOF) { clear(); while(m--) { scanf("%d%d%d",&u,&v,&c); addEdge(u,v,c); } scanf("%d%d%d",&st,&en,&k); dij(en); if(dis[st]==inf) { puts("-1"); continue; } if(st == en) k++; printf("%d\n",a_star(st)); } return 0; }
相关文章推荐
- K短路-POJ-2449
- 【POJ 2449】Remmarguts' Date(A*+dij求k短路)
- POJ 2449 Remmarguts' Date k短路
- POJ 2449 Remmarguts' Date [A*算法 K短路]
- 【解题报告】POJ 2449 Remmarguts' Date -- 有向图第k短路(有重边)
- 【K短路】【A星】Remmarguts' Date POJ 2449 A-Star
- POJ 2449 Remmarguts' Date(k短路)
- POJ 2449 Remmarguts' Date 第K短路 A*
- k短路 SPFA+A*算法 poj 2449
- poj 2449Remmarguts' Date uvaoj 10740 not the best dijkstra或spfa或bellman-ford k短路 A*
- POJ 2253 - 最短路变形 SPFA+Dijstra
- POJ 2449 第K短路 SPFA+A*
- POJ 3255 Roadblocks(Dijstra 求次短路长度)
- POJ 2449 A* K短路
- poj 2449 (A* + Dijsktra 求K短路)
- POJ 2449 Remmarguts' Date (A*搜索求K短路)
- POJ 2449 A*k短路
- POJ 2449 Remmarguts' Date(A* - 第K短路)
- POJ 2449 Remmarguts' Date (第k短路)
- poj 2449 Remmarguts' Date(第K短路)