题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2544
题目意思很简单,就是给你n+1个点,m条路径,你要找到从编号为1的点到编号为n的点的最短距离。
先上floyd 的代码吧。
#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
int main()
{
int i,j,k,e[105][105],n,m;
while(cin>>n>>m&&n&&m){
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
e[i][j]=inf;//在没输入路径之前,任意不同两点都不可到达
if(i==j)
e[i][j]=0;//若到达的点为本身,则距离为0;
}
}
for(i=0;i<m;i++){
int x,y,z;
cin>>x>>y>>z;//输入路径,该图为无向图,故应该x 到 y,y 到 x都赋值;
e[x][y]=z;
e[y][x]=z;
}
for(k=1;k<=n;k++){//floyd算法核心代码,k代表中转点
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(e[i][j]>e[i][k]+e[k][j])//如果中转之后的距离比没中转的距离小的话,更新两点之间的距离
e[i][j]=e[i][k]+e[k][j];
}
}
}
cout<<e[1][n]<<endl;
}
}
可能有人误将floyd算法核心代码理解成了对每个中转点都尝试一遍,得出只中转一次的最短距离,事实上不是这样,这段代码是先以1为中转点,更新所有能以1作为中转点得到更短距离的点,然后中转点2是在已经通过中转点1更新了所有点之间的距离的情况下再进行更新一遍,之后的中转点也以此类推。所以这段代码是通过多个中转点得出最短距离。
PS:以我的表述能力只能说到这种程度啦。
好了,floyd看完了,接下来上djkstra代码吧
#include<bits/stdc++.h>
using namespace std;
const int maxn=105;
int e[maxn][maxn],book[maxn],n,m,inf=0x3f3f3f3f;
void djk(){
book[1]=1;
int i,j,k;
for(i=0;i<n-1;i++){
int mi=inf,u;
for(j=1;j<=n;j++){//找到距离起始点(1)最近的点
if(e[1][j]<mi&&!book[j]){
mi=e[1][j];
u=j;
}
}
book[u]=1;//标记这个点,表示从起始点到该点的距离已经确定为最短,不需再更新距离。
for(k=1;k<=n;k++){
//if(e[u][k]<inf)
if(e[1][k]>e[1][u]+e[u][k])//尝试是否能通过中转点u得到更短距离
e[1][k]=e[1][u]+e[u][k];//其实一般这里都是用dis[k]的,不过我也懒得改了就还是写成了e[1][k]
}
}
}
int main(){
int i,j;
while(cin>>n>>m&&n&&m){
memset(book,0,sizeof(book));
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){//这段代码的作用我已在floyd上进行了解释,此处不在作解释
e[i][j]=inf;
if(i==j)
e[i][j]=0;
}
}
for(i=0;i<m;i++){
int x,y,z;
cin>>x>>y>>z;
e[x][y]=z;
e[y][x]=z;
}
djk();
cout<<e[1][n]<<endl;
}
}