题目:
题目网址:Problem - 2544 (hdu.edu.cn)
思路:
给定n个路口,m个道路,求由第1个路口到第m个路口的最短距离;
先将道路的长度双向存储在一个数组里,在用Dijkstra算法预处理,找到最后第一个点的最优距离;
Dijkstra算法:定义三个数组,
第一个用于存储所给点到该点的最短距离,
第二个对于存储到该点的上一个路径点,没有则为-1,
第三个标记该点是否为最优解;
首先对所给起点联通的道路进行处理,把道路距离记录在第一个数组,
并同时记录上一个点,所有道路都循环完在对第一个数组里找最短的路径标记为最优在对其进行上述操作,直至最后;
最后输出最优解;
代码实现:
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int N=104,maxn=100000000; int d[N],w[N][N],vis[N],n,m; void Dijkstra(int src){ for(int i=1;i<=n;i++) d[i]=maxn;//先将距离都设置为最大 d[src]=0;//起点设置为0 memset(vis,0,sizeof(vis));//标记都不是最优解 for(int i=1;i<=n;i++) { int u=-1; for(int j=1;j<=n;j++) if(!vis[j])//判断是否为最优解 if(u==-1||d[j]<d[u])//选定下一个最优解进行下面的累加操作 u=j; vis[u]=1; for(int j=1;j<=n;j++) if(!vis[j])//判断是否为最优解 { int tmp=d[u]+w[u][j];//进行距离累加 if(tmp<d[j])//如果比存储的值小则替换 d[j]=tmp; } } } int main(){ int a,b,c; while(cin>>n>>m&&n+m){ for(int i=1;i<=n;i++){//进行预处理道路长度都为最大值 w[i][i]=maxn; for(int j=i+1;j<=n;++j) w[i][j]=w[j][i]=maxn; } for(int i=0;i<m;i++){ cin>>a>>b>>c;//输入道路长度存储入数组 w[a][b]=w[b][a]=c; } Dijkstra(1);//以1起点进行dijkstra处理 cout<<d[n]<<endl; } return 0; }
补充:Floyd算法
#include<iostream> #include<algorithm> using namespace std; const int N=105; const int INF=100000000; int n, m, d[N][N]; int a,b,c; inline void read_graph(){//数组初始化 for(int i=1; i<=n; ++i){ d[i][i] = INF; for(int j=i+1; j<=n; ++j) d[i][j]=d[j][i]=INF; } int a,b,c; for(int e=1; e<=m; ++e){//数据输入 cin>>a>>b>>c; d[a][b]=d[b][a]=c; } } inline void Floyd(int src){//Floyd算法循环 for(int k=1; k<=n; ++k){ for(int i=1; i<=n; ++i){ for(int j=1; j<=n; ++j) if(d[i][k]<INF && d[k][j]<INF){ d[i][j] = min(d[i][j], d[i][k]+d[k][j]); } } } } int main(){ while(cin>>n>>m&&n+m){ read_graph(); Floyd(1); cout<<d[1][n]<<endl; } return 0; }