/*
HDU 2544 最短路经典入门
dijkstra算法,注意模型,点更新
floy算法:深刻理解每个 for 循环意义
spfa算法:使用到队列,每个点最后一次被踢出的就是其最短路,可以自己画画模型
*/
#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
#define manx 120
#define inf 99999999
int g[manx][manx];
int n,m,dist[manx];
bool s[manx]; /// 加入集合,就标记为 1
void dijkstra(int st,int ed){
for(int i=1;i<=ed;i++){ /// 保存直接相连的路径距离
s[i]=0; /// 初始化
dist[i]=g[st][i];
}
s[st]=1; dist[st]=0;
for(int i=1;i<=n;i++){
int temp =inf; /// 无穷大路径长度
int ans = -1; /// 最短点的下标
for(int j=1;j<=n;j++){
if(!s[j] && dist[j]<temp){
temp = dist[j];
ans = j;
}
}
if(ans==-1) break;
s[ans]=1;
for(int j=1;j<=n;j++){ /// 更新
if(!s[j]&&dist[j]>dist[ans]+g[ans][j])
dist[j]=dist[ans]+g[ans][j];
}
}
}
void floy(){
for(int k=1;k<=n;k++) /// 借助点
for(int i=1;i<=n;i++) /// 起点
for(int j=1;j<=n;j++) /// 终点
if(g[i][j]>g[i][k]+g[k][j])
g[i][j]=g[j][i]=g[i][k]+g[k][j];
}
void spfa(int st){
queue<int>que;
while(!que.empty()) que.pop();
for(int i=1;i<=n;i++){
s[i]=0;
dist[i]=inf;
}
s[st]=1; dist[st]=0;
que.push(st);
while(!que.empty()){
int te = que.front();
que.pop();
s[te]=0; /// 抵消标记
for(int i=1;i<=n;i++){
if(dist[i]>dist[te]+g[te][i]){
dist[i] = dist[te]+g[te][i]; //// 更新
if(!s[i]) {
que.push(i);
s[i]=1;
}
}
}
}
}
int main(){
while(cin>>n>>m,n&&m){
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
g[i][j]=inf;
int a,b,c;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&a,&b,&c);
if(g[a][b]>c)
g[a][b]=g[b][a]=c;
}
// dijkstra(1,n);
// printf("%d\n",dist[n]);
// floy();
// printf("%d\n",g[1][n]);
spfa(1);
printf("%d\n",dist[n]);
}
}
最短路
最新推荐文章于 2024-10-25 19:32:27 发布