dijkstra算法
#求其他点到源点x的最短距离。
#找一个离源点最近的点,进行n-1次这样的操作。
#每找一个点,就进行一次松弛操作,把所有点都松弛一遍。
#重点
1 初始化点与点之间的距离,自身的距离为0,到其他点的距离为inf
2 双向边
注意
memset不能这样用,不可以把变量的值作为第二个参数,只能用常量。
int e[100][100];
int inf=0xffffffff;
memset(e,inf,sizeof(e));
之前写的时候为了省力,使用memset,但是运行结果一直不正确。输出数组e的值,发现其值都变成了-1,本来赋的却是inf。
所以,最后还是使用for循环赋值,不能把变量作为memset的第二个参数。
代码:
//源点到其他点的最短距离
#include<stdio.h>
#include<string.h>
using namespace std;
int inf=0xffffff;
int e[100][100];//假如有一百个点
int book[100];
int dis[100];
void dij(int n,int x){
book[x]=1;
for(int i=1;i<n;i++){
int min_=inf;
int t;
//找一个到源点最近的点
for(int j=1;j<=n;j++)
{
if(dis[j]<min_&&!book[j]){
min_=dis[j];
t=j;
}
}
//标记
book[t]=1;
//松弛
for(int k=1;k<=n;k++){
if(dis[t]+e[k][t]<dis[k])
dis[k]=dis[t]+e[k][t];
}
}
}
int main(){
//到源点x的最短距离
int n,x,m;
int u,v,w;
scanf("%d%d%d",&n,&m,&x);//n个点 m条边 求到x点的最短距离
//初始化点到点之间的距离 自身到自身的距离设置为0
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(i==j)
e[i][j]=0;
else
e[i][j]=inf;
}
memset(book,0,sizeof(book));
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
e[u][v]=w;
e[v][u]=w;
}
for(int i=1;i<=n;i++)
dis[i]=e[x][i];
dij(n,x);
for(int i=1;i<=n;i++)
printf("%d ",dis[i]);
}
测试数据
输入数据:
6 9 1
1 2 1
1 3 12
2 3 9
2 4 3
3 5 5
4 3 4
4 5 13
4 6 15
5 6 4
输出数据:
0 1 8 4 13 17