没有什么说的。代码中讲解的应该还算明确。
但是我想说的是一定要把最短路径和最小生成树给分开。。最小生成树是求一个Graph(这个图中必定是全部联通图)中,求解所有子树中所有路径之和最小的子树。。而最短路径则求Graph中是从一个点到另一个点路径之和最短的路径。这完全是两个问题。。没有任何联系!
#include <iostream>
#include <cstdio>
#include <string>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <map>
#include <queue>
#include <stack>
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a));
#define For(a,b) for(int i = a;i<b;i++)
#define LL long long
#define MAX_N 100010
#define VN 10
using namespace std;
typedef int Vextype;
typedef int Adjtype;
typedef int Elemtype;
typedef struct
{
Vextype vexs[VN];
Adjtype arcs[VN][VN];
}Graph; //邻接矩阵的存储结构
typedef struct
{
Adjtype length;
int prevex;
}Path;//Dijkstra算法中的操作对象
typedef struct
{
Adjtype weight[VN][VN];
int nextVex[VN][VN];
}ShortPath;//Floyd算法中的操作对象
Elemtype Dijk_flag = 1;//判断该点是否到所有点都有通路的标志
Elemtype mark[VN][VN];//记录原始邻接矩阵的数据元素
/*
初始化Dijkstra algorithm中的dis数组。
其实也就是将0到Graph中所有的点的距离
以及所有点的前驱(0),置于dis数组
如果说没有通路。则置为-1。
*/
void init(Graph * graph,Path dis[],Elemtype node_num)
{
dis[0].length = 0;
dis[0].prevex = 0;
graph->arcs[0][0] = 1;
for(int i = 1; i<node_num; i++)
{
dis[i].length = graph->arcs[0][i];
if(dis[i].length != MAX_N)
{
dis[i].prevex = 0;
}
else
dis[i].prevex = -1;
}
}
void Dijkstra(Graph * pgraph,Path dis[],Elemtype node_num)
{
init(pgraph,dis,node_num);
int minw,minVex;
/*
这个for循环每循环一次找到一个
距离初始点的最短距离的点
*/
for(int i = 1; i<node_num; i++)
{
minw = MAX_N;
minVex = 0;
/*
该for循环是为了找到当前dis数组中最小的length值
*/
for(int j = 1; j<node_num; j++)
{
if(pgraph->arcs[j][j] == 0 && dis[j].length < minw)
{
minw = dis[j].length;
minVex = j;
}
}
/*
此判断是该Graph是否所有的点可以连成一个通路
如果不能·则用全局变量Dijk_flag标记
*/
if(minVex == 0)
{
Dijk_flag = 0;
break;
}
pgraph->arcs[minVex][minVex] = 1;
/*
更新dis数组中剩下的元素中的前驱和length值
*/
for(int j = 1; j<node_num; j++)
{
if(pgraph->arcs[j][j] == 0 && dis[j].length > dis[minVex].length + pgraph->arcs[minVex][j])
{
dis[j].length = dis[minVex].length + pgraph->arcs[minVex][j];
dis[j].prevex = minVex;
}
}
}
}
void Floyd(Graph *pgraph,ShortPath *ppath,Elemtype node_num)
{
/*
初始化ppath结构体中的数组元素。
如果从i点到j点有通路,则nextVex[i][j] = j;
否则等于-1。
不论是否有通路,都将weight值赋予weight[i][j].
*/
for(int i = 0; i<node_num; i++)
{
for(int j = 0; j<node_num; j++)
{
if(pgraph->arcs[i][j] != MAX_N)
{
ppath->nextVex[i][j] = j;
}
else
ppath->nextVex[i][j] = -1;
ppath->weight[i][j] = pgraph->arcs[i][j];
}
}
/*
每次外层循环k不变,就相当于喜欢是每次将k点插入i到j的路径当中去。
这样遍历一遍求最短Graph中可以连通的点中。每两个点之间的最短路径。
*/
for(int k = 0; k<node_num; k++)
for(int i = 0; i<node_num; i++)
for(int j = 0 ; j<node_num; j++){
if(ppath->weight[i][k] >= MAX_N || ppath->weight[k][j] >= MAX_N)
continue;
if(ppath->weight[i][j] > ppath->weight[i][k] + ppath->weight[k][j])
{
ppath->weight[i][j] = ppath->weight[i][k] + ppath->weight[k][j];
ppath->nextVex[i][j] = ppath->nextVex[i][k];
}
}
}
int main()
{
Graph pgraph;
Path dis[VN];
ShortPath shpath;
int node_num = 6;
int edge_num = 11;
for(int i = 0; i<node_num; i++)
{
for(int j = 0; j<node_num; j++){
if(i==j) mark[i][j] = 0;
else mark[i][j] = MAX_N;
}
}
int node_start,node_stop,edge_val = 0;
for(int i = 0; i<edge_num; i++)
{
cin>>node_start>>node_stop>>edge_val;
mark[node_start][node_stop] = edge_val;
}
/*
为arcs邻接矩阵数组赋初值
*/
for(int i = 0; i<node_num; i++)
{
for(int j = 0; j<node_num; j++)
{
pgraph.arcs[i][j] = mark[i][j];
}
}
Dijkstra(&pgraph,dis,node_num);
if(Dijk_flag)
{
cout<<"该图中所有的结点连通,且这是一个连通图。"<<endl<<endl;
}
else
cout<<"这个图中存在不可访问到的结点,所以这不是一个连通图。"<<endl<<endl;
cout<<"1 — 0的最短路径长度是: "<<endl<<dis[1].length<<endl<<endl;
cout<<"1 — 0的最短路径是:"<<endl;
cout<<"V_1 -> ";
int prev = 1;
while(1)
{
prev = dis[prev].prevex;
cout<<"V_"<<prev<<" -> ";
if(prev == 0)
{
cout<<endl<<endl;
break;
}
}
/*
由于经过Dijkstra算法的调用,arcs数组中一些元素已被改变。
所以需要再次对arcs数组进行初始化。
*/
for(int i = 0; i<node_num; i++)
{
for(int j = 0; j<node_num; j++)
{
pgraph.arcs[i][j] = mark[i][j];
}
}
Floyd(&pgraph,&shpath,node_num);
cout<<"0 — 1的最短路径长度是: "<<endl<<shpath.weight[0][1]<<endl<<endl;
cout<<"0 — 1的最短路径是:"<<endl;
cout<<"V_0 -> ";
int next = shpath.nextVex[0][1];
while(1)
{
cout<<"V_"<<next<<" -> ";
next = shpath.nextVex[next][1];
if(next == 1)
{
cout<<"V_1"<<endl<<endl;
break;
}
}
//system("pause");
return 0;
}
/*
2016.10.7
测试样例:
0 1 50
0 2 10
0 4 45
1 2 15
1 4 5
2 0 20
2 3 15
3 1 20
3 4 35
4 3 30
5 3 3
*/