1. 题目
示例输入
6
0 1 4 10000 10000 10000
1 0 2 7 5 10000
4 2 0 10000 1 10000
10000 7 10000 0 3 2
10000 5 1 3 0 6
10000 10000 10000 2 6 0
示例输出
0
1
3
7
4
9
分析:求一个结点到所有结点的距离,可以使用Dijkstra算法。
狄克斯特拉算法解决图中一点到其余各点到最短路径的问题。
其基本思想为:图G=(V,E)是一个有权有向图,把顶点V分成两组,第一组为已求出最短路径的点的集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径v,…k,就将k加入到集合S中,直到全部到点都加入S集合中,算法结束),第二组为其余未确定最短路径的点的集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入到S中。
2. 代码
#include <iostream>
using namespace std;
typedef struct{
int n;
int Edge[100][100];
}Graph;
Graph G;
int dist[100]; //储存路径长度(最终更新后储存的是最短路径)
bool visited[100]; //相当于记录顶点是否被加入终点集合
// 读入图的顶点和边(邻接矩阵)
void createGraph(){
cin >> G.n;
for(int i=0; i<G.n; i++){
for(int j=0; j<G.n; j++){
cin >> G.Edge[i][j];
}
}
}
// Dijkstra方法,求出顶点s到其他每个顶点的最短路径长度
void Dijkstra(int t){
//首先初始化
for(int i=0; i<G.n; i++){
dist[i] = G.Edge[t][i];
}
visited[t] = true;
// n-1次更新,每次更新都将一个顶点加入visited
// 最后所有顶点都被遍历过
for(int i=1; i<G.n; i++){
//首先是选出最小的dist并进行记录为tmp
int minn = 10000, tmp = 0;
for(int i=0; i<G.n; i++){
if(!visited[i] && dist[i] < minn){
minn = dist[i];
tmp = i;
}
}
// 将tmp加入终点集合,并对dist进行更新,记录path
visited[tmp] = true;
for(int i=0; i<G.n; i++){
if(!visited[i]){
dist[i] = min(dist[i], minn + G.Edge[tmp][i]);
}
}
}
}
int main(int argc, char** argv) {
createGraph();
Dijkstra(0);
for(int i=0; i<G.n; i++){
cout << dist[i] << endl;
}
return 0;
}