一、Dijkstra算法
#include<iostream>
using namespace std;
const int maxint = 10000;
class Dij{
public:
void initial(int m, int n);
void read_case();
void dijkstra(int begin, int end);
void search_path(int begin, int end);// 查找从源点v到终点u的路径,并输出
private:
int path[101][101];// 图的两点间路径长度
int distance[101];// 当前点到源点的最短路径长度
int pre[101];// 记录当前点的前一个结点
bool visited[101];
int node_num;// 图的结点数
int edge_num;// 图的路径数
};
void Dij::initial(int m, int n){
node_num = m;
edge_num = n;
for (int i = 0; i < 101; i++){
for (int j = 0; j < 101; j++){
path[i][j] = maxint;
}
distance[i] = maxint;
}
memset(visited, false, sizeof(visited));
}
void Dij::read_case(){
int n1, n2, len;
for (int i = 1; i <= edge_num; i++){
cin >> n1 >> n2 >> len;
path[n1][n2] = path[n2][n1] = len;
}
}
void Dij::dijkstra(int begin, int end){
int i, j, k;
for (i = 1; i <= node_num; i++){
distance[i] = path[begin][i];
if (distance[i] == maxint)
pre[i] = 0;
else
pre[i] = begin;
}
distance[begin] = 0;
visited[begin] = true;
for (i = 2; i <= node_num; i++){
int min = maxint;
// 找出当前未使用的点j的distance[j]最小值
for (j = 1; j <= node_num; j++){
if (distance[j] < min&&!visited[j]){
k = j;
min = distance[j];
}
}
// 表示k点已被访问过
visited[k] = true;
// 更新distance[j]
for (j = 1; j <= node_num; j++){
if (min + path[k][j] < distance[j] && !visited[j]){
distance[j] = min + path[k][j];
pre[j] = k;
}
}
}
cout << "源点到最后一个顶点的最短路径长度: " << distance[end] << endl;
}
// 查找从源点v到终点u的路径,并输出
void Dij::search_path(int begin, int end){
int que[101];
int count = 1;
que[count] = end;
count++;
int tmp = pre[end];
while (tmp != begin){
que[count] = tmp;
count++;
tmp = pre[tmp];
}
que[count] = begin;
cout << "源点到最后一个顶点的路径为: ";
for (int i = count; i >= 1; i--)
if (i != 1)
cout << que[i] << " -> ";
else
cout << que[i] << endl;
}
int main(){
int n, line;
Dij x;
int start, end;
while (cin >> n >> line){
x.initial(n, line);
x.read_case();
cin >> start >> end;
x.dijkstra(start, end);
x.search_path(start, end);
}
return 0;
}
二、Floyd算法
#include<iostream>
using namespace std;
const int max_num = 500;//最大城市数
const int max_len = 10000;//两城市间路径长度最大不超过10000
class Street{
public:
void init(int n, int m);
void read_case();
void floyd();
void search_path();
private:
int city[max_num][max_num];//路径权重数组
int path[max_num][max_num];//保存最短路径数组,记录前继
int city_num;//城市数
int road_num;//城市间路径数
int start;
int end;
};
void Street::init(int n, int m){
city_num = n;
road_num = m;
for (int i = 0; i < max_num; i++){
for (int j = 0; j < max_num; j++){
if (i == j)
city[i][j] = 0;//注意自己对自己长度必须设为0
else
city[i][j] = max_len;
path[i][j] = j;
}
}
}
void Street::read_case(){
int c1, c2, len;
for (int i = 0; i < road_num; i++){
cin >> c1 >> c2 >> len;
city[c1][c2] = city[c2][c1] = len;
}
cin >> start >> end;
}
void Street::floyd(){
for (int k = 0; k < road_num; k++){
for (int i = 0; i < road_num; i++){
for (int j = 0; j < road_num; j++){
if (city[i][k] + city[k][j] < city[i][j]){
city[i][j] = city[i][k] + city[k][j];
path[i][j] = path[i][k];
}
}
}
}
cout << city[start][end] << endl;
}
void Street::search_path(){
int k = path[start][end];
cout << start;
while (k != end){
cout << " -> " << k;
k = path[k][end];
}
cout << " -> " << end << endl;
}
int main(){
int n, m;
Street s;
while (cin >> n >> m){
s.init(n, m);
s.read_case();
s.floyd();
s.search_path();
}
return 0;
}