一.Dijikstra算法
注意:计算最短路径时,需要把邻接矩阵中没有边的位置初始化为无穷大;此处以INF表示,INF可以取0x3f3f3f3f,不能直接设为INT_MAX(因为做加法时会上溢)。
测试用图:
其邻接矩阵表示为:
vector> test_graph(7, vector(7, INF));
test_graph[0][1] = 20;
test_graph[0][2] = 50;
test_graph[0][3] = 30;
test_graph[1][2] = 25;
test_graph[1][5] = 70;
test_graph[2][3] = 40;
test_graph[2][4] = 25;
test_graph[2][5] = 50;
test_graph[3][4] = 55;
test_graph[4][5] = 10;
test_graph[4][6] = 70;
test_graph[5][6] = 50;
其中INF为:
const int INF = 0x3f3f3f;//不能取得太大(dijikstra中会用到,其余情况没边用0表示即可)
代码:
//pre记录前缀
const int INF = 0x3f3f3f;//不能取得太大(dijikstra中会用到,其余情况没边用0表示即可)
void dijkstra(graph g, vector& lowcost, vector& pre, int beg) {//第二、三个参数为传出参数,分别表示从源节点beg,到所有节点的最短路路径
size_t N = g.cost.size();
vector visited(N, false);
for (size_t i = 0;i < N;++i) {//初始化lowcost和pre
lowcost[i] = INF;
pre[i] = -1;
}
lowcost[beg] = 0;//出发点到自己的最短路径是0
for (size_t i = 0;i < N;++i) {
int newNode = -1;//下一个要被选中的点的编号, 初始化为 - 1
int MinWeight=INF;//与当前节点相邻的边的最小权值
//第一个for,遍历所有的未被访问过的节点,选中间点(已选节点之外的离出发点距离最短的点)
for (size_t j = 0;j < N;++j) {
if (!visited[j] && lowcost[j] < MinWeight) {
MinWeight = lowcost[j];
newNode = j;
}
}
if(-1==newNode)
break;//图不连通时,退出
visited[newNode] = true;//将中间点标记为已访问状态
for (size_t j = 0;j < N;++j) {
if (!visited[j] && lowcost[newNode] + g.cost[newNode][j] < lowcost[j]){
lowcost[j] = lowcost[newNode] + g.cost[newNode][j];
pre[j] = newNode;
}
}
}
}
步骤:
1.初始化时,将出发点到自己的最短路径置为0,其余置为无穷
2.对于出发点以外的点(即上面第二个for中所选的点j),考察从出发点直接到它的距离d1=lowcost[j]和先经过一个第一个for所选的中间点(newNode)才到j的距离d2=lowcost[newNode] + g.cost[newNode][j];
3.如果经由中间点然后访问点j的距离比直接访问j的距离短,即步骤2中的d2 测试部分: 测试结果:graph g;
g.cost = test_graph;
g.vertex = { "v1","v2","v3","v4","v5","v6","v7" };
vector