poj 2449( k 短路 spfa+A*来求解)
2011-10-03 21:19
260 查看
看到了一个讲解k短路的感觉不错。。。。。
对于A* ,估价函数 = 当前值+当前位置到终点的距离,即 F(p)=g(p)+h(p),每次扩展估价函数值中最小的一个。对于k短路来说,g(p)为当前从s到p所走的长度,h(p)为从p到 t 的最短路的长度,则F(p)的意义就是从s按照当前路径走到 p 后要走到终点 t 一共至少要走多远。也就是说我们每次的扩展都是有方向的扩展,这样就可以提高求解速度和降低扩展的状态数目。为了加速计算,h(p)需要从A*搜索之前进行预处理,只要将原图的所有边反向,再从终点
t 做一次单源最短路径就可以得到每个点的h(p)了。
还有就是这个题意说是t到s的k短路。。但样例给的是s到t的所以就在写程序的时候求s到t的就可以了。。囧。。
对于A* ,估价函数 = 当前值+当前位置到终点的距离,即 F(p)=g(p)+h(p),每次扩展估价函数值中最小的一个。对于k短路来说,g(p)为当前从s到p所走的长度,h(p)为从p到 t 的最短路的长度,则F(p)的意义就是从s按照当前路径走到 p 后要走到终点 t 一共至少要走多远。也就是说我们每次的扩展都是有方向的扩展,这样就可以提高求解速度和降低扩展的状态数目。为了加速计算,h(p)需要从A*搜索之前进行预处理,只要将原图的所有边反向,再从终点
t 做一次单源最短路径就可以得到每个点的h(p)了。
还有就是这个题意说是t到s的k短路。。但样例给的是s到t的所以就在写程序的时候求s到t的就可以了。。囧。。
#include<cstdio> #include<iostream> #include<cstring> #include<queue> using namespace std; #define inf 1<<30 #define cc(m,v) memset(m,v,sizeof(m)) #define M 100005 struct node { int v, g, f, next; // f=g+h bool operator<(const node & t) const { if (t.f == f) return t.g < g; return t.f<f; } } edge[M], edge1[M]; int head[1005], p, head1[1005], n, dis[1005]; void spfa(int s) { int u, v, i, j, cot[1005]; queue<int> q; bool vis[1005]; for (i = 0; i <= n; i++) dis[i] = inf, cot[i]=0, vis[i]=0; vis[s] = 1, dis[s] = 0, q.push(s); while (!q.empty()) { u = q.front(),q.pop(), vis[u] = 0, cot[u]++; if(cot[u]>=n) return ; for (j = head1[u]; j != -1; j = edge1[j].next) if (dis[v=edge1[j].v] > dis[u] + edge1[j].g) { dis[v]=dis[u]+edge1[j].g; if(!vis[v]) vis[v] = 1, q.push(v); } } } int a_star(int s, int t, int k) { int cnt = 0, i; struct node e, ne; priority_queue<node> que; if (s == t) k++; if (dis[s] == inf) return -1; e.v = s, e.g = 0, e.f = e.g + dis[e.v]; que.push(e); while (!que.empty()) { e = que.top(), que.pop(); if (e.v == t) { cnt++; if (cnt == k) return e.g; } for (i = head[e.v]; i != -1; i = edge[i].next) { ne.v = edge[i].v, ne.g = e.g + edge[i].g; ne.f = ne.g + dis[ne.v], que.push(ne); } } return -1; } void ainit() { p = 0, cc(head, -1), cc(head1, -1); } void addedge(int u, int v, int w) { edge[p].v = v, edge[p].g = w, edge[p].next = head[u], head[u] = p; edge1[p].v = u, edge1[p].g = w, edge1[p].next = head1[v], head1[v] = p++; } int main() { int s, m, t, u, v, w, i, k; while (scanf("%d%d", &n, &m) != -1) { ainit(); for (i = 1; i <= m; i++) { scanf("%d%d%d", &u, &v, &w); addedge(u, v, w); } scanf("%d%d%d", &s, &t, &k); spfa(t); printf("%d\n", a_star(s, t, k)); } return 0; }
相关文章推荐
- poj 2449 Remmarguts' Date 第k短路 A*+spfa 解题报告
- poj 2449 第k短路 A* + spfa
- poj 2449 Remmarguts' Date--k短路--spfa+A*
- POJ 2449 Remmarguts' Date 第K短路 A* + SPFA
- poj2449 Remmarguts' Date --- k短路模板(SPFA+A*)
- Remmarguts' Date POJ - 2449 第k短路 SPFA+A*
- poj 2449 Remmarguts' Date 求第k短路(SPFA+A*)
- POJ 2449 第K短路 SPFA+A*
- poj 2449 求第k最短路 A* + SPFA
- POJ---2449 Remmarguts' Date[K短路入门题(Dijkstra()||Spfa()+A*)]
- POj 2449 Remmarguts' Date K短路 A*+SPFA
- POJ 题目2449 Remmarguts' Date(K短路,A*+spfa)
- poj 2449Remmarguts' Date uvaoj 10740 not the best dijkstra或spfa或bellman-ford k短路 A*
- POJ 2449 Remmarguts' Date ( Dijkstra + A* 求解第K短路 )
- POJ 2449 A* + spfa求第k短路
- POJ 2449 Remmarguts' Date A*+spfa求第k最短路
- POJ 2449 Remmarguts' Date(A*+SPFA)K短路问题
- [POJ 2449] Remmarguts' Date 第K短路
- poj 3255 Roadblocks 次短路 spfa 解题报告
- poj 2240 Arbitrage 最短路变形 spfa