#include<iostream>
using namespace std;
int main(){
int e[10][10],dis[10],book[10],i,j,n,m,b1,b2,z3,u,v,min;//book数组用来标记
int inf=99999999;//用inf(infinity的缩写)存储一个我们认为的无穷大值
cout<<"请输入顶点个数n和边的条数m:"<<endl;
cin>>n>>m;
//初始化
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(i==j){
e[i][j]=0;
}
else
e[i][j]=inf;
}
}
//读入边
cout<<"请依次输入m条边,每条边起点为b1,终点为b2,权重为z3。即b1->b2(z3):"<<endl;
for(i=1;i<=m;i++){
//读入每一条边
cin>>b1>>b2>>z3;
e[b1][b2]=z3;
}
//初始化dis数组,这里是1号顶点到其余各个顶点的初始路程
for(i=1;i<=n;i++){
dis[i]=e[1][i];
}
//book数组初始化
for(i=1;i<=n;i++){
book[i]=0;
}
book[1]=1;//顶点1被标记
//Dijkstra算法核心语句
for(i=1;i<=n-1;i++){
//找到离1号顶点最近的顶点,由于1号顶点已经被标记,所以只需n-1轮
min=inf;
for(j=1;j<=n;j++){
if(book[j]==0&&dis[j]<min){
min=dis[j];
u=j;
}
}
book[u]=1;
for(v=1;v<=n;v++){
if(e[u][v]<inf){
if(dis[v]>dis[u]+e[u][v]){
dis[v]=dis[u]+e[u][v];
}
}
}
}
//输出最终结果
cout<<endl<<"1号顶点到其余各个顶点的最短路径为: "<<endl;
for(i=1;i<=n;i++){
cout<<dis[i]<<" ";
}
return 0;
}
/*//
int n,m,i,k;
//u,v,w数组大小要根据实际情况来设置,要比m的最大值大1
int u[6],v[6],w[6];
//first要比n的最大值大1,next要比m的最大值大1
int first[5],next[5];
cout<<"请输入顶点个数n和边的条数m:"<<endl;
cin>>n>>m;
//初始化first数组下标1~n的值为-1,表示1~n顶点暂时都没有边
//first数组表示各个顶点的第一条边的编号(重点就是它只是一个编号)
for(i=1;i<=n;i++){
first[i]=-1;
}
cout<<"请依次输入m条边,每条边起点为u,终点为v,权重为w。即u->v(w):"<<endl;
//建立邻接表
for(i=1;i<=m;i++){
//读入每一条边
cin>>u[i]>>v[i]>>w[i];
//u[i]是指第i条边的起始顶点u;
//v[i]是指第i条边的终止顶点v;
//w[i]是指第i条边的路径长度w;
//下面两句是建立邻接表的关键——>核心就是给读入的每条边依次进行1~m的编号,为每个顶点插入边的时候都是直接插入"链表"的首部
//所以遍历某个顶点的所有边时,遍历顺序正好和读入顺序相反
next[i]=first[u[i]];
first[u[i]]=i;
}
/*
这里是通过数组来实现邻接表,而没有使用真正的指针链表,这是一种在实际应用中非常容易实现的方法。这种方法为每个顶点i
(i从1~n)都设置了一个链表,里面保存了从顶点i出发的所有边(用first数组和next数组实现)
*/
/*
//遍历1号结点的每条边
k=first[1];
while(k!=-1){
cout<<u[k]<<v[k]<<w[k];
k=next[k];
}
//遍历每个结点的所有边
for(i=1;i<=n;i++){
k=first[i];
while(k!=-1){
cout<<u[k]<<v[k]<<w[k];
k=next[k];
}
}
*/
//*/
6.2Dijkstra算法——通过边实现松弛
最新推荐文章于 2022-05-22 20:54:50 发布