堆优化迪杰斯特拉,堆顶元素取出后要立刻弹出
查看原帖
堆优化迪杰斯特拉,堆顶元素取出后要立刻弹出
533003
_EEA_楼主2023/5/21 15:45

下面的代码是错误的,测评记录:

dis[s] = 0;
que.push(make_pair(0, s));
while(que.size()){
	if(mk[que.top().second]){
		que.pop();
		continue;
	}
	mk[que.top().second] = 1;
	for(auto ptr = mp[que.top().second].begin(); ptr < mp[que.top().second].end(); ++ptr){
		if(dis[que.top().second] + ptr->second < dis[ptr->first]){
			dis[ptr->first] = dis[que.top().second] + ptr->second;
			que.push(make_pair(-dis[ptr->first], ptr->first));
		}
	}
	que.pop();
}

改为用 tmp 接住堆顶元素立刻弹出后,就过了:

dis[s] = 0;
que.push(make_pair(0, s));
while(que.size()){
	tmp = que.top().second;
	que.pop();
	if(mk[tmp]) continue;
	mk[tmp] = 1;
	for(auto ptr = mp[tmp].begin(); ptr < mp[tmp].end(); ++ptr){
		if(dis[tmp] + ptr->second < dis[ptr->first]){
			dis[ptr->first] = dis[tmp] + ptr->second;
			que.push(make_pair(-dis[ptr->first], ptr->first));
		}
	}
}

我猜可能是因为用堆顶元素进行松弛操作后,新入堆的元素会改变堆顶元素,但仔细想,新入堆的元素最短路是不可能比原来的堆顶元素小的啊,不会改变堆顶元素。

原本这是个求助帖,写到一半自己突然想明白了。考虑权值为 00 的边,松弛后新进堆的元素最短路跟堆顶元素相等,可能改变堆顶元素。可能有其他人会跟我犯同样的错误,所以还是把帖子发出来作为提醒吧。

2023/5/21 15:45
加载中...