存图改用数组模拟邻接表的方式:存单向图
数组模拟邻接表详见 邻接表的数组实现 。
迪杰斯特拉 详见点击打开链接。
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; const int MAX_SIZE=110; const int INF=2e9+1e8; int start[MAX_SIZE],terminal[MAX_SIZE],value[MAX_SIZE]; int first[MAX_SIZE],next[MAX_SIZE],dis[MAX_SIZE],vis[MAX_SIZE]; int main() { int n,m,i,j,minn,k; while(scanf("%d %d",&n,&m)!=EOF) // n个点m条边 { if(n==m&&m==0) return 0; for(i=1; i<=n; i++) // 初始化 first 数组 first[i]=-1; for(i=1; i<=m; i++) // 存入m条边 { scanf("%d %d %d",&start[i],&terminal[i],&value[i]); next[i]=first[start[i]]; first[start[i]]=i; } // 初始化 dis 数组 k=first[1]; for(i=1; i<=n; i++) dis[i]=INF; while(k!=-1) { dis[terminal[k]]=value[k]; k=next[k]; } memset(vis,0,sizeof(vis)); // 标记当前位置是否来过 0 表示还没有来过 vis[1]=1; int mid_pos; int times=n-1; // 迪杰斯特拉 核心代码 while(times--) { minn=INF; for(j=1; j<=n; j++) { if(vis[j]==0&&dis[j]<minn) { minn=dis[j]; mid_pos=j; } } if(minn==INF) continue; vis[mid_pos]=1; // 遍历 pos 点能到的地方 k=first[mid_pos]; while(k!=-1) { if(dis[mid_pos]+value[k]<dis[terminal[k]]) dis[terminal[k]]=dis[mid_pos]+value[k]; k=next[k]; } } for(i=1; i<=n; i++) printf("%d ",dis[i]); printf(" "); } return 0; } /* 6 9 1 2 1 1 3 12 2 3 9 2 4 3 3 5 5 4 3 4 4 5 13 4 6 15 5 6 4 */