堆优化的dijkstra(手写堆)

利用小根堆优化每次查找dis数组最短距离的复杂度

只要看过小根堆,这个代码并不难,但有细节需要处理

我是手写堆,但用priority_queue更简单

#include
using namespace std;
const int maxn=1000;
int f[maxn][maxn];
int vis[maxn];
int d[maxn];
const int inf=999999;
int len;
struct dot{
	int xu;
	int va;
}dis[maxn];//设置结构体,保存节点的序号和值 
//手写堆的push操作 
void push(dot n){ 
	dis[++len]=n;
	int son=len;
	while(son/2){
		if(dis[son/2].va>dis[son].va){
			swap(dis[son/2],dis[son]);
		    son/=2;
		}
		else break;
	}
}
//pop操作 
dot pop(){
	dot tp=dis[1];
	swap(dis[1],dis[len--]);
	int pa=1,son=2;
	while(son<=len){
		if(dis[son].va>dis[son+1].va&&sondis[pa].va)
		   break;
		 swap(dis[son],dis[pa]);
		 pa=son;
		 son=pa*2;
	}
	return tp;
}
int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=m;i++){
		int x,y,z;
		cin>>x>>y>>z;
		f[x][y]=f[y][x]=z;
	}
	fill(d,d+maxn,inf);
	push({1,0});
	d[1]=0;
	while(len){
		dot tp=pop();
		if(vis[tp.xu])//由于一个点的最短距离会多次改变,
		//所以堆中可能会有多个重复节点 ,但每次取出的是最小的,所以被取出一次后,
		//后面的重复节点都可以忽略 
		 continue;
		vis[tp.xu]=1;
		for(int i=1;i<=n;i++){
		   if(f[tp.xu][i]&&!vis[i]&&d[i]>f[tp.xu][i]+tp.va)
		   {
		   	push({i,f[tp.xu][i]+tp.va});
		   	d[i]=f[tp.xu][i]+tp.va;//d的值不要忘了改 
		   }
		}
	}
	cout<

 

你可能感兴趣的:(图)