单源最短路径——迪杰斯特拉算法

伪代码:

Dijkstra(G,d[],s){
	初始化;
	for(循环n次){
		u = 使d[u]最小的还未被访问的顶点的标号;
		记u已被访问;
		for(从u出发能到达的所有顶点v){
			if(v未被访问 && 以u为中介点使s到顶点v的最短距离d[v]更优){
				优化d[v]; 
			}
		} 
	} 
}

邻接矩阵版:

这里对应上面“u = 使d[u]最小的还未被访问的顶点的标号;”这个方法是用上面那个for循环实现的


const int maxn = 1000;   
const int INF = 100000000;
int n,G[maxn][maxn];         //n为顶点数目,G是存储图边的邻接矩阵 
int d[maxn];       //起点到达各点的最短路径长度
bool vis[maxn] = {false};   //标记数组,vis[i] == true表示已被访问过 

void Dijstra(int s){
	fill(d,d+maxn,INF);   //fill函数将整个数组赋值为INF 
	d[s] = 0;
	for(int i = 0;i <n;i++){    //循环n(次)个顶点 
		int u = -1,MIN = INF;      //u使d[u]最小,MIN存放该最小的d[u] 
		for(int j = 0;j <n;j++){    //找到未访问的顶点中d[]最小的 
			if(vis[j] == false && d[j] <MIN){
				u = j;
				MIN = d[j];
			}
		}
		//找不到小于INF的d[u],说明剩下的顶点和起点s不连通 
		if(u == -1) return;
		vis[u] = true;     //标记u为已访问 
		for(int v = 0;v <n;v++){
			//如果v未访问&&u能到达v&&以u为中介点可以使d[v]更优 
			if(vis[v] == false && G[u][v] != INF && d[u] + G[u][v] <d[v]){
				d[v] = d[u] + G[u][v];     //优化d[v] 
			}
		}
	}
}

代码的整体说明如下,其实还是蛮费解的= =,感觉就是比较巧妙的两个循环交叠
代码说明
邻接表版:


const int maxn = 1000;
const int INF = 100000000;
struct Node{
	int v,dis;    //v为边的目标顶点,dis为边权 
};

vector<Node>Adj[maxn];
int n;
int d[maxn];
bool vis[maxn] = {false};

void Dijkstra(int s){
	fill(d,d+maxn,INF);
	d[s] = 0;
	for(int i = 0;i <n;i++){
		int u = -1,MIN = INF;
		for(int j = 0;j <n;j++){
			if(vis[j] == false && d[j] <MIN){
				u = j;
				MIN = d[j];
			}
		}
		if(u == -1) return;
		vis[u] = true;
		//只有下面这个for与邻接矩阵写法不同
		for(int j = 0;j <Adj[u].size();j++){
			int v = Adj[u][j].v;
			if(vis[v] == false && d[u]+Adj[u][j].dis <d[v]){
				d[v] = d[u] + Adj[u][j].dis;
			}
		}  
	}
}
发布了212 篇原创文章 · 获赞 6 · 访问量 6419

猜你喜欢

转载自blog.csdn.net/weixin_42377217/article/details/104231655