题目大意:
输入N,M,N表示有多多少个路口,M表示有多少条街道,接着输入M行,每行输入a,b,c 三个数表示,从a路口走到b路口要花c分钟,题目要求计算从1路口走到N路口所花的最短时间。
算法思想:
1.将m条街道的信息存入邻接矩阵中,因为是无向图,所以邻接矩阵是对称的。
2.进行一个初始化操作,首先用d[]数组存储源节点到其它节点的最短距离,初始时置为无穷大。
3.用S集合存储源节点集合,初始时置空。
4.将所有节点如队列。
5.依次选取队列中d[i]小的元素,将该元素加入s集合,同时更新d[],重复这些操作直至队列空为止。
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN=10010;
const int INFINMAX=99999999;
int C[105][105];//邻接矩阵用于存储每条道路
int d[105];//存储每个节点到源节点间的最小距离
int pre[105];//存储每个节点的前驱节点
int S[105];//设置顶点集合S
typedef struct {
int node[105];
int n;//记录队列中共有多少个元素
}Queue;
Queue Q;
/*初始化源节点*/
void INITALIZE_SINGLE_SOURCE(int N,int s){
for(int i=1;i<=N;i++){
d[i]=INFINMAX;//初始时距离源节点为无穷大
pre[i]=0;
}
d[s]=0;
}
/*松弛函数*/
void Relax(int u,int v,int w){
if(d[v]>d[u]+C[u][v]){
d[v]=d[u]+C[u][v];
pre[v]=u;//修改前驱
}
}
void DIJKSTRA(int N,int s){
INITALIZE_SINGLE_SOURCE(N,s);
memset(S,0,sizeof(S));//初始时将S集合全部置空
memset(Q.node,0,sizeof(Q.node));//队列置空
Q.n=0;
for(int i=1;i<=N;i++){
Q.node[i]=1;//所有顶点进队列
Q.n++;
}
while(Q.n!=0){//队列不空
int u=s,min=INFINMAX;
for(int i=1;i<=N;i++)
{
if(d[i]<min&&Q.node[i]){//要保证该顶点在队列中
min=d[i];
u=i;
}
}
Q.node[u]=0;//出队列操作
Q.n--;
S[u]=1;
for(int v=1;v<=N;v++){//
if(C[u][v]){
Relax(u,v,C[u][v]);
}
}
}
}
int main(){
int N,M;
while(cin>>N>>M&&N&&M){
int a,b,c;
memset(C,0,sizeof(C));//邻接矩阵初始化
for(int i=0;i<M;i++){
cin>>a>>b>>c;
C[a][b]=c;
C[b][a]=c;
}
DIJKSTRA(N,1);
cout<<d[N]<<endl;
}
return 0;
}