题意很明确啦,
最短路的floyd算法。老套路,先给官方定义:
floyd算法又称插点法,是一种用于寻找给定的加权图中两点间最短路径的算法。算法主要有两步:1、从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大;
2、对于每一对顶点 u和v,看看是否存在一个顶点w使得从u到w再到v比已知的路径更短,如果是,更新它。
这个叫动态转移方程:pri[j][k]=min(pri[j][k],pri[j][i]+pri[i][k]);其中j,k是要求最短路径的两点,i为其中间的若干点。不断取最短路径pri[j][k]
这个算法虽然好理解,但因为有三重for循环,所以当数据较大时,容易超时。。。
代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define INF 0x3f3f3f//无穷大
#define MAXN 105
using namespace std;
int m,n;
int pri[MAXN][MAXN];
void floyd(){
for(int i=1;i<=n;i++)//中间点,下标都是从1开始!
for(int j=1;j<=n;j++)//两端点
for(int k=1;k<=n;k++)
pri[j][k]=min(pri[j][k],pri[j][i]+pri[i][k]);//不断更新最短路径
}
int main(){
while(scanf("%d%d",&n,&m),(m||n)){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(i==j)
pri[i][j]=0;//对角线即自己到本身的距离为0
else
pri[i][j]=INF;//全部初始化为无穷
}
int a,b,time;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&a,&b,&time);
if(pri[a][b]>time)
pri[a][b]=pri[b][a]=time;//存入数据
}
floyd();
printf("%d\n",pri[1][n]);//输出1到n的最短路径
}
return 0;
}
再来一个Dijkstra算法:Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。这个算法虽然比floyd省时,但它较为复杂,难以理解。。floyd可以求任意两点间的最短路,而Dijkstra属于单源算法,只能求一点到任意点的距离!
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f
#define MAXN 105
int pri[MAXN][MAXN];//记录两个点之间的距离
int dis[MAXN];//起点到该点的最短距离
int vis[MAXN];//标记数组
int n,m;
void dijkstra(){
memset(vis,0,sizeof(vis));
vis[1]=1;
for(int i=2;i<=n;i++)
dis[i]=pri[1][i];
for(int i=1;i<=n;i++){
int min=INF;//用来记录最小距离
int next;//下一个要判断的点
for(int j=1;j<=n;j++){
if(!vis[j]&&dis[j]<min){
min=dis[j];
next=j;
}
}//每次先找出最短距离存在,该点记为next
vis[next]=1;//新加入的点做标记
for(int j=1;j<=n;j++)
if(!vis[j]&&dis[j]>dis[next]+pri[next][j]){
dis[j]=dis[next]+pri[next][j];
}//每加入一个顶点,更新到达各个顶点的距离
}
}
int main(){
while(scanf("%d%d",&n,&m),n||m){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(i==j)
pri[i][j]=0;
else
pri[i][j]=INF;
}
int a,b,c;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&a,&b,&c);
if(pri[a][b]>c)//防止重边
pri[a][b]=pri[b][a]=c;
}
dijkstra();
printf("%d\n",dis[n]);
}
return 0;
}