可以求得单个节点src到所有节点的最短路
按照非递减的顺序找出各个节点的最短路
/**维护直到flag全部为true
* flag :是否已经找到最短路, 初始化全部false
* dist :目前的最短距离 ,初始化全部正无穷INT32_MAX
* path :最短路径的上一个节点, 初始化全部-1
* 三个数组
* */
int Dijkstra(int src, int dest, vector<int> &dist, vector<int> &path, vector<vector<int>> &MAT)
{
int N = MAT.size();
if (src < 0 || src >= N)
{
cout << "src不在节点0 - (N-1)之间" << endl;
return -1;
}
vector<bool> flag(N, false); //标记找到最短路的节点
//初始化
for (int i = 0; i < N; i++)
{
if (MAT[src][i] != 0)
{
dist[i] = MAT[src][i];
path[i] = src;
}
}
dist[src] = 0;
flag[src] = true;
int min_v = -1;
int min_dis = INT32_MAX;
while (1)
{
min_v = -1;
min_dis = INT32_MAX;
//没有找到最短路的flag[i]=false中最小的距离,已经是最短距离了
for (int i = 0; i < N; i++)
{
if (!flag[i])
{
if (dist[i] < min_dis) //要带 = 吗????
{
min_dis = dist[i];
min_v = i;
}
}
}
//出口,都找到最短路了
if (min_v == -1)
break;
for (int i = 0; i < N; i++)
{
if (MAT[min_v][i] != 0) //有直接相连边
{
if (dist[min_v] + MAT[min_v][i] < dist[i]) //更新路径
{
dist[i] = dist[min_v] + MAT[min_v][i];
path[i] = min_v;
}
}
}
flag[min_v] = true;
}
//下面这部分只是输出信息了,要不要无所谓
{
cout << src << "-" << dest << "最短路径长度为: " << dist[dest] << endl;
cout<<"路径为: "<<endl;
stack<int> PATH;
int id = dest;
PATH.push(dest);
while (path[id] != -1)
{
PATH.push(path[id]);
id = path[id];
}
while (!PATH.empty())
{
cout << PATH.top() << " ";
PATH.pop();
}
cout << endl;
}
return dist[dest];
}
求得所有节点之间的最短路径
//初始化距离矩阵DIST和MAT差不多,对角元素0(自己到自己最短距离),有直接相连的节点初始化为MAT[i][j],没有直接相连的初始化为正无穷INT32_MAX
//path全部是-1
void Floyd(vector<vector<int>>& DIST, vector<vector<int>>& path, vector<vector<int>>& MAT)
{
int N=MAT.size();
for(int k=0;k<N;k++)
{
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
if(DIST[i][k]+DIST[k][j] >0 && DIST[i][k]+DIST[k][j]<DIST[i][j]) //DIST[i][k]+DIST[k][j] >0 是因为,但凡有一个是INT32_MAX,结果就是小于0的
{
DIST[i][j]=DIST[i][k]+DIST[k][j];
path[i][j]=k;
}
}
}
}
}
#include
#include
#include
using namespace std;
//单源最短路
int Dijkstra(int src, int dest, vector<int> &dist, vector<int> &path, vector<vector<int>> &MAT);
//多源最短路
void Floyd(vector<vector<int>>& DIST, vector<vector<int>>& path, vector<vector<int>>& MAT);
void print_path(int src, int dest, vector<vector<int>>& path);
int main()
{
vector<vector<int>> MAT = {{0, 2, 0, 3, 3, 0, 0},
{0, 0, 1, 2, 0, 0, 0},
{0, 0, 0, 1, 0, 0, 3},
{0, 0, 0, 0, 3, 5, 3},
{0, 0, 0, 0, 0, 2, 0},
{0, 0, 0, 0, 0, 0, 4},
{0, 0, 0, 0, 0, 0, 0}};
int N = MAT.size();
for (int i = 0; i < N; i++)
{
for (int j = i + 1; j < N; j++)
{
MAT[j][i] = MAT[i][j]; //对称矩阵
}
}
//Dijkstra 单源最短路
int src;
cout << "输入src:";
cin >> src;
int dest;
cout << "输入dest:";
cin >> dest;
vector<int> dist(N, INT32_MAX);
vector<int> path(N, -1);
Dijkstra(src, dest, dist, path, MAT);
//Floyd 多源最短路
//初始化距离矩阵DIST和MAT差不多,对角元素0(自己到自己最短距离),有直接相连的节点初始化为MAT[i][j],没有直接相连的初始化为正无穷INT32_MAX
vector<vector<int>> DIST(N,vector<int>(N,INT32_MAX));
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
if(i==j)
{
DIST[i][j]=0;
}
else if(MAT[i][j]!=0)
{
DIST[i][j]=MAT[i][j];
}
}
}
vector<vector<int>> floyd_path(N,vector<int>(N,-1));
Floyd(DIST,floyd_path, MAT);
// for(int i=0;i
// {
// for(int j=0;j
// {
// cout<
// }
// cout<
// }
// cout<
// for(int i=0;i
// {
// for(int j=0;j
// {
// cout<
// }
// cout<
// }
cout<<endl;
cout<<src<<"-"<<dest<<"最短路径距离: "<<DIST[src][dest]<<endl;
cout<<"路径为:"<<endl;
print_path(src,dest,floyd_path);cout<<dest<<endl;
return 0;
}
/**
* 维护直到flag全部为true
* flag :是否已经找到最短路, 初始化全部false
* dist :目前的最短距离 ,初始化全部正无穷INT32_MAX
* path :最短路径的上一个节点, 初始化全部-1
* 三个数组
* */
int Dijkstra(int src, int dest, vector<int> &dist, vector<int> &path, vector<vector<int>> &MAT)
{
int N = MAT.size();
// cout<<"N = "<
if (src < 0 || src >= N)
{
cout << "src不在节点0 - (N-1)之间" << endl;
return -1;
}
vector<bool> flag(N, false); //标记找到最短路的节点
//初始化
for (int i = 0; i < N; i++)
{
if (MAT[src][i] != 0)
{
dist[i] = MAT[src][i];
path[i] = src;
}
}
dist[src] = 0;
flag[src] = true;
int min_v = -1;
int min_dis = INT32_MAX;
while (1)
{
min_v = -1;
min_dis = INT32_MAX;
//没有找到最短路的flag[i]=false中最小的距离,已经是最短距离了
for (int i = 0; i < N; i++)
{
if (!flag[i])
{
if (dist[i] < min_dis) //要带 = 吗????
{
min_dis = dist[i];
min_v = i;
}
}
}
//出口,都找到最短路了
if (min_v == -1)
break;
for (int i = 0; i < N; i++)
{
if (MAT[min_v][i] != 0) //有直接相连边
{
if (dist[min_v] + MAT[min_v][i] < dist[i]) //更新路径
{
dist[i] = dist[min_v] + MAT[min_v][i];
path[i] = min_v;
}
}
}
flag[min_v] = true;
}
//下面只是输出信息了,要不要无所谓
cout << src << "-" << dest << "最短路径长度为: " << dist[dest] << endl;
cout<<"路径为: "<<endl;
stack<int> PATH;
int id = dest;
PATH.push(dest);
while (path[id] != -1)
{
PATH.push(path[id]);
id = path[id];
}
while (!PATH.empty())
{
cout << PATH.top() << " ";
PATH.pop();
}
cout << endl;
return dist[dest];
}
//初始化距离矩阵DIST和MAT差不多,对角元素0(自己到自己最短距离),有直接相连的节点初始化为MAT[i][j],没有直接相连的初始化为正无穷INT32_MAX
//path全部是-1
void Floyd(vector<vector<int>>& DIST, vector<vector<int>>& path, vector<vector<int>>& MAT)
{
int N=MAT.size();
for(int k=0;k<N;k++)
{
for(int i=0;i<N;i++)
{
for(int j=0;j<N;j++)
{
if(DIST[i][k]+DIST[k][j] >0 && DIST[i][k]+DIST[k][j]<DIST[i][j]) //DIST[i][k]+DIST[k][j] >0 是因为,但凡有一个是INT32_MAX,结果就是小于0的
{
DIST[i][j]=DIST[i][k]+DIST[k][j];
path[i][j]=k;
}
}
}
}
}
void print_path(int src, int dest, vector<vector<int>>& path)
{
if(path[src][dest]==-1) //中间谁都不隔
{
cout<<src<<" ";
return;
}
int k=path[src][dest];//中间经过k
print_path(src,k,path);
print_path(k,dest,path);
}