前段时间用到单向和双向dijkstra去跑地图,比对时间
今天来把双向dijkstra的模板放到这里
/*
比起单向来说,双向dijkstra将搜索半径缩小到原来的1/2,理想情况下,相同地图时间缩小至少一半
下面的模板以无向图为例
猜想:双向dijkstra只适用于无向图
为何双向dijkstra中不需要用bool型st数组?
答:可以从小的地方思考,如果这个点恰巧是最优解的点,如果被正向搜索过标记后,则永远不会被后向
搜索到,那么当计算min_dis=d1[u]+d2[u],会导致d2[u]永远为无穷,那么则永远得不到最优解,
最小距离都是用相同的结点确定的,
*/
#include<iostream>
#include<queue>
using namespace std;
typedef pair<int, int> PII;
const int N = 1010;
int h[N], ne[N], e[N], idx;
int w[N];
int d1[N], d2[N];
void add(int a, int b, int c)
{
w[idx] = c;
e[idx] = b;
ne[idx] = h[a];
h[a] = idx;
idx++;
}
int bin_dijkstra(int s,int t)
{
int min_dis = 999999;
d1[s] = 0;
d2[t] = 0;
priority_queue<PII, vector<PII>, greater<PII> >heap_s, heap_t;
heap_s.push({ 0,s });
heap_t.push({ 0,t });
while (heap_s.size() && heap_t.size())
{
auto t1 = heap_s.top(); heap_s.pop();
int ver = t1.second;
min_dis = min(min_dis, d1[t1.second] + d2[t1.second]);
for (int i = h[ver]; i != -1; i = ne[i])
{
int j = e[i];
if (d1[j] > t1.first + w[i])
{
d1[j] = t1.first + w[i];
heap_s.push({ d1[j],j });
}
}
auto t2 = heap_t.top(); heap_t.pop();
ver = t2.second;
min_dis = min(min_dis, d1[ver] + d2[ver]);
for (int i = h[ver]; i != -1; i = ne[i])
{
int j = e[i];
if (d2[j] > t2.first + w[i])
{
d2[j] = t2.first + w[i];
heap_t.push({ d2[j],j });
}
}
if (heap_s.size() && heap_t.size())
{
auto t1 = heap_s.top(); int ver1 = t1.second;
auto t2 = heap_t.top(); int ver2 = t2.second;
if (d1[ver1] + d2[ver2] >= min_dis)break;//停止条件
}
}
return min_dis;
}
int main()
{
memset(h, -1, sizeof h);
memset(d1, 0x3f, sizeof d1);
memset(d2, 0x3f, sizeof d2);
for (int i = 0; i < 10; i++)
{
int a, b, c;
cin >> a >> b >> c;
add(a, b, c);
add(b, a, c);
}
cout << bin_dijkstra(1, 9) << endl;
}
/*
1 2 1
2 3 1
3 4 1
4 8 1
8 9 2
1 5 8
5 7 2
9 7 6
6 9 1
1 6 4
**答案是:5**
*/