单源点最短路径问题,毫不犹豫的dijkstra。
这个题只搞个起点终点,那就输出终点对应的那个最短路径值就OK了。
人生第一个dijkstra,所以把注释写得无比详细。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define N 201
#define maxint 1000000
using namespace std;
int map[N][N];//每两个城镇之间的距离,没有路就是maxint
int dis[N];//从起点到各个点的距离,不能到达就是maxint
bool flag[N];//标记某个点是否已进入最短路径集合,true表示进入
int start,end,town,road;
void dijkstra();
int main()
{
int i,j,a,b,len;
while(scanf("%d%d",&town,&road) != EOF )
{
memset(flag,false,sizeof(flag));//初始,最短路径集合没有点
for(i = 0 ; i < town ; ++i)
{
for(j = 0 ; j < town ; ++j)
map[i][j] = maxint;//都赋值为maxint
}
for(i = 0 ;i < town ; ++i)
map[i][i] = 0 ;//自己到自己距离为0
for(i = 0 ;i < road ; ++i)
{
scanf("%d%d%d",&a,&b,&len);
if(len < map[a][b] )//两城镇间可能有多条路,只要最短的那条
map[a][b] = map[b][a] = len;
}
scanf("%d%d",&start,&end);
dijkstra();
if(dis[end] != maxint)//如果有路
printf("%d\n",dis[end]);
else//没有路,无法到达
puts("-1");
}
//system("pause");
return 0;
}
void dijkstra()
{
int i,j,u,temp,newdis;
for(i = 0 ; i < town ; ++i)
dis[i] = map[start][i];//从起点到其他各点的距离
dis[start] = 0;
flag[start] = true;//起点进入最短路径集合
for(i = 1 ; i < town ; ++i )
{
temp = maxint;
for(j = 0 ; j < town ; ++j)
if( !flag[j] && dis[j] < temp)//从还未进入最短路径集合的点中找一个离起点最近的点
{
u = j ; temp = dis[j];
}
flag[u] = true;//将这个新的点加入最短路径集合
/*
为什么每次都是根据新加入的那个点来更新未加入的点离起点的距离呢?
因为经过新加入的到达其余各点,路径可能最短,而且最终每个点都会进入最短路径集合,
所以所有的“拐弯”路径都考虑到了。
*/
for(j = 0 ; j < town ; ++j)//根据新的点更新还未加入的点离起点的距离
{
if( !flag[j] && map[u][j] < maxint)//该点未加入最短路径集合,并且从u可以到达该点
{
newdis = dis[u] + map[u][j];
if(newdis < dis[j])//中间经过u会使路径更短
dis[j] = newdis;
}
}
}//for(i)
}