双向dijkstra

前段时间用到单向和双向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**
 
 */
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值