搜索 ( 第K短路, A*搜索)——Remmarguts' Date ( POJ 2449 )
2016-08-01 15:34
591 查看
题目链接:
http://poj.org/problem?id=2449
分析:
给出N个点和M条边,求从点S到点T的第K短路,每个点可以被经过多次。
A*搜索:
估价函数f(x)=g(x)+h(x)
g(x)为从初始状态转移到x状态的代价,
h(x)为下界函数(x 状态转移到T状态还需要的花费)
题解:
将图的边反向,以t为源点,求t到所有点的的最短路,并把这个最短路作为下界函数h(x)的值。
用一个优先队列存以S为起点的路径对应的终点x,f(x),g(x)
从优先队列中弹出f(x)最小的点x,如果点x就是t,计算t出队的次数,如果当前为t的第k次出队,则当前路径的长g(x)就是s到t的第k短路的长度。
否则遍历与x相连的所有的边,将扩展出的路径信息加入优先队列,进行重复操作。
代码:
1.建图:
2.SPFA求最短路:
3.A*搜索:
AC代码:
http://poj.org/problem?id=2449
分析:
给出N个点和M条边,求从点S到点T的第K短路,每个点可以被经过多次。
A*搜索:
估价函数f(x)=g(x)+h(x)
g(x)为从初始状态转移到x状态的代价,
h(x)为下界函数(x 状态转移到T状态还需要的花费)
题解:
将图的边反向,以t为源点,求t到所有点的的最短路,并把这个最短路作为下界函数h(x)的值。
用一个优先队列存以S为起点的路径对应的终点x,f(x),g(x)
从优先队列中弹出f(x)最小的点x,如果点x就是t,计算t出队的次数,如果当前为t的第k次出队,则当前路径的长g(x)就是s到t的第k短路的长度。
否则遍历与x相连的所有的边,将扩展出的路径信息加入优先队列,进行重复操作。
代码:
1.建图:
int e; struct node { int v, w, next; }edge[MaxM], revedge[MaxM]; int head[MaxN], revhead[MaxN];//revhead为反向建图 void init() { e = 0; memset(head, -1, sizeof(head)); memset(revhead, -1, sizeof(revhead)); } void Add(int x, int y, int w) {//邻接链表 edge[e].v = y; edge[e].w = w; edge[e].next = head[x]; head[x] = e; revedge[e].v = x; revedge[e].w = w; revedge[e].next =revhead[y]; revhead[y] = e++; }
2.SPFA求最短路:
int vis[MaxN], d[MaxN], q[MaxM*5]; void SPFA(int src) { for(int i = 1; i <= N; i++) d[i] = INF; memset(vis, 0, sizeof(vis)); vis[src] = 0; int h = 0, t = 1; q[0] = src; d[src] = 0; while(h < t) { int u = q[h++]; vis[u] = 0; for(int i = revhead[u] ; i != -1; i = revedge[i].next) { int v = revedge[i].v; int w = revedge[i].w; if(d[v] > d[u] + w) { d[v] = d[u] + w; if(!vis[v]) { q[t++] = v; vis[v] = 1; } } } } }
3.A*搜索:
struct A { int f, g, v; bool operator <(const A a)const { if(a.f == f) return a.g < g; return a.f < f; } }; int Astar(int src, int des) { int cnt = 0; priority_queue<A>Q; if(src == des) K++; if(d[src] == INF) return -1; A t, tt; t.v = src, t.g = 0, t.f = t.g + d[src]; Q.push(t); while(!Q.empty()) { tt = Q.top(); Q.pop(); if(tt.v == des) { cnt++; if(cnt == K) return tt.g; } for(int i = head[tt.v]; i != -1; i = edge[i].next) { t.v = edge[i].v; t.g = tt.g + edge[i].w; t.f = t.g + d[t.v]; Q.push(t); } } return -1; }
AC代码:
#include <cstdio> #include <iostream> #include <cstdlib> #include <cstring> #include <algorithm> #include <cmath> #include <cctype> #include <stack> #include <map> #include <set> #include <queue> using namespace std; typedef pair<int,int> Pii; typedef long long LL; typedef unsigned long long ULL; typedef double DBL; typedef long double LDBL; #define MST(a,b) memset(a,b,sizeof(a)) #define CLR(a) MST(a,0) #define Sqr(a) ((a)*(a)) #define MaxN 1005 #define MaxM 500005 #define INF 1000000000 int N,M; int S,T,K; struct node { int v, w, next; }edge[MaxM], revedge[MaxM]; int head[MaxN], revhead[MaxN]; int e, vis[MaxN], d[MaxN], q[MaxM * 5]; struct A { int f, g, v; bool operator <(const A a)const { if(a.f == f) return a.g < g; return a.f < f; } }; void init() { e = 0; memset(head, -1, sizeof(head)); memset(revhead, -1, sizeof(revhead)); } void Add(int x, int y, int w) { edge[e].v = y; edge[e].w = w; edge[e].next = head[x]; head[x] = e; revedge[e].v = x; revedge[e].w = w; revedge[e].next =revhead[y]; revhead[y] = e++; } void SPFA(int src) { for(int i = 1; i <= N; i++) d[i] = INF; memset(vis, 0, sizeof(vis)); vis[src] = 0; int h = 0, t = 1; q[0] = src; d[src] = 0; while(h < t) { int u = q[h++]; vis[u] = 0; for(int i = revhead[u] ; i != -1; i = revedge[i].next) { int v = revedge[i].v; int w = revedge[i].w; if(d[v] > d[u] + w) { d[v] = d[u] + w; if(!vis[v]) { q[t++] = v; vis[v] = 1; } } } } } int Astar(int src, int des) { int cnt = 0; priority_queue<A>Q; if(src == des) K++; if(d[src] == INF) return -1; A t, tt; t.v = src, t.g = 0, t.f = t.g + d[src]; Q.push(t); while(!Q.empty()) { tt = Q.top(); Q.pop(); if(tt.v == des) { cnt++; if(cnt == K) return tt.g; } for(int i = head[tt.v]; i != -1; i = edge[i].next) { t.v = edge[i].v; t.g = tt.g + edge[i].w; t.f = t.g + d[t.v]; Q.push(t); } } return -1; } int main() { init(); while( ~scanf("%d%d", &N, &M) ) { for(int i=0;i<M;i++) { scanf("%d%d%d", &S, &T, &K); Add(S, T, K); } scanf("%d%d%d", &S, &T, &K); SPFA(T); printf("%d\n", Astar(S, T)); } return 0; }
相关文章推荐
- 【POJ 2449】Remmarguts's Date (A*搜索第k短路)
- POJ 2449 Remmarguts' Date 第k短路 A*搜索
- [POJ 2449] Remmarguts' Date 第K短路
- POJ 2449 Remmarguts' Date [第k短路]
- Remmarguts' Date----POJ_2449----第k最短路
- poj2449 Remmarguts' Date,第K短路
- POJ 2449 Remmarguts' Date A*+spfa求第k最短路
- POJ 2449 Remmarguts' Date (第k短路 A*搜索算法模板)
- 【A* + 第K短路】 poj2449 Remmarguts' Date
- Remmarguts' Date POJ - 2449 第k短路 SPFA+A*
- poj 2449 Remmarguts' Date 第k短路 A*+spfa 解题报告
- 第k短路(POJ 2449: Remmarguts' Date)
- poj 2449 Remmarguts' Date(A*+Dijsktra 求第K短路)
- POJ - 2449 Remmarguts' Date 第k短路 Astar
- poj 2449 Remmarguts' Date 求第k短路(SPFA+A*)
- POJ 2449 Remmarguts' Date (求第K短路,A* + Dijkstra)
- [第K短路]POJ_2449_Remmarguts' Date
- POJ 2449 Remmarguts' Date(第k短路+spfa+A*搜索)
- POJ:2449-Remmarguts' Date(单源第K短路)
- poj_2449 Remmarguts' Date(第k短路+Dijkstra+A*)