poj--2449 Remmarguts' Date(k短路)
2016-09-16 20:32
399 查看
Remmarguts’ Date
SPFA + A*算法。
A*算法通过一个估价函数f(h)来估计图中的当前点p到终点的距离,并由此决定它的搜索方向,当这条路径失败时,它会尝试其他路径。
估价函数 = 当前值+当前位置到终点的距离,即f(p)=g(p)+d(p)
其中,g(p)为当前从s到p所走的路径长度,d(p)为从点p到终点t的最短路长度,f(p)则为从s到p再到t的路径长度。
也就是说,每次的扩展是有方向的,它会选择估价函数值最小的一条路径走。
d(p)可以在A*搜索之前进行预处理,只要将原图的所有边反向,再从终点t做一次单源最短路径就能得到每个点的d(p)值。
具体步骤:
将有向图的所有边反向,以t为源点,计算t到其他点的最短路d[].
建一个优先队列,将s加入到队列中;
从优先队列中弹出f(p)最小的点p,如果p就是t,计算t出队的次数,如果已经是t的第k次出队,那么当前路径的长度就是s到t的第k短路的长度;否则遍历与p相连的所有边,将扩展出的到p的邻接点信息加入到优先队列。
注意当 s == t 的时候,需要计算 k + 1 短路,因为s到t这条距离为0的路径不能算在这k短路中。
题解
求s到t的第k短路的长度。SPFA + A*算法。
A*算法通过一个估价函数f(h)来估计图中的当前点p到终点的距离,并由此决定它的搜索方向,当这条路径失败时,它会尝试其他路径。
估价函数 = 当前值+当前位置到终点的距离,即f(p)=g(p)+d(p)
其中,g(p)为当前从s到p所走的路径长度,d(p)为从点p到终点t的最短路长度,f(p)则为从s到p再到t的路径长度。
也就是说,每次的扩展是有方向的,它会选择估价函数值最小的一条路径走。
d(p)可以在A*搜索之前进行预处理,只要将原图的所有边反向,再从终点t做一次单源最短路径就能得到每个点的d(p)值。
具体步骤:
将有向图的所有边反向,以t为源点,计算t到其他点的最短路d[].
建一个优先队列,将s加入到队列中;
从优先队列中弹出f(p)最小的点p,如果p就是t,计算t出队的次数,如果已经是t的第k次出队,那么当前路径的长度就是s到t的第k短路的长度;否则遍历与p相连的所有边,将扩展出的到p的邻接点信息加入到优先队列。
注意当 s == t 的时候,需要计算 k + 1 短路,因为s到t这条距离为0的路径不能算在这k短路中。
#include <iostream> #include <cstdio> #include <algorithm> #include <vector> #include <queue> #include <cstring> using namespace std; const int maxn = 1000 + 3; const int inf = 0x3f3f3f3f; struct Edge{ int to, w; Edge(int to, int w):to(to), w(w){} }; vector<Edge> G1[maxn], G2[maxn]; int n, m, s, t, k; int d[maxn]; bool vis[maxn]; void SPFA(){ memset(vis, 0, sizeof(vis)); for(int i = 1; i <= n; ++i) d[i] = inf; queue<int> Q; Q.push(t); d[t] = 0, vis[t] = true; while(!Q.empty()){ int u = Q.front();Q.pop(); vis[u] = false; for(int i = 0; i < G2[u].size(); ++i){ int v = G2[u][i].to, w = G2[u][i].w; if(d[v] > d[u] + w){ d[v] = d[u] + w; if(!vis[v]){ vis[v] = true; Q.push(v); } } } } } struct Node{ int to; int g, f; // f = g + d Node(int to, int g, int f):to(to), g(g), f(f){} bool operator < (const Node& rhs) const{ return rhs.f == f ? rhs.g < g : rhs.f < f; } }; int Astar(int s, int t){ priority_queue<Node> PQ; if(s == t) k++; if(d[s] == inf) return -1; PQ.push(Node{s, 0, d[s]}); // to, g, f while(!PQ.empty()){ Node x = PQ.top(); PQ.pop(); if(x.to == t){ if(--k == 0) return x.g; } for(int i = 0; i < G1[x.to].size(); ++i){ int v = G1[x.to][i].to, w = G1[x.to][i].w; PQ.push(Node(v, x.g + w, x.g + w + d[v])); } } return -1; } int main(){ #ifdef EXMY freopen("data.in", "r", stdin); #endif // EXMY /// 15264K 329MS while(~scanf("%d %d", &n, &m)){ for(int i = 0; i <= n; ++i){ G1[i].clear(); G2[i].clear(); } int u, v, w; for(int i = 0; i < m; ++i){ scanf("%d %d %d", &u, &v, &w); G1[u].push_back(Edge(v, w)); G2[v].push_back(Edge(u, w)); // 反向图 } scanf("%d %d %d", &s, &t, &k); SPFA(); //for(int i = 1; i <= n; ++i) cout << d[i] << " "; printf("%d\n", Astar(s, t)); } return 0; }
相关文章推荐
- [A* K短路] POJ 2449 Remmarguts' Date
- POJ 2449 Remmarguts' Date (A*+K短路)
- 【POJ 2449】Remmarguts' Date(A*+dij求k短路)
- poj 2449 Remmarguts' Date 第k短路 A*+spfa 解题报告
- POJ 2449 Remmarguts' Date(A*+SPFA)K短路问题
- [第K短路]POJ_2449_Remmarguts' Date
- poj 2449 Remmarguts' Date(第K短路 A*)
- POJ 2449 Remmarguts' Date 第K短路 A* + SPFA
- poj2449 Remmarguts' Date --- k短路模板(SPFA+A*)
- POJ 2449 Remmarguts' Date(K短路)
- POJ:2449-Remmarguts' Date(单源第K短路)
- Poj 2449 Remmarguts' Date(Astar K短路)
- Poj 2449 Remmarguts' Date (第k短路)
- poj 2449 Remmarguts' Date(A*求第K短路)
- poj 2449 Remmarguts' Date--k短路--spfa+A*
- POJ 2449 Remmarguts' Date(A* - 第K短路)
- POJ 2449 Remmarguts' Date (第k短路 A*搜索算法模板)
- POJ 2449 Remmarguts' Date ( Dijkstra + A* 求解第K短路 )
- poj2449 Remmarguts' Date A*K短路
- POJ 2449 Remmarguts' Date 求K短路