个人心得:Dijkstra算法是贪心思想的一种延伸,注意路径pre,pre数组表示此时最短路径中的前一个顶点。每次更新到目的点时更新;
从源点出发,更新路径,然后找出此时最短的点,然后以这个点为头,看能否缩减路程,
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<iomanip> #include<algorithm> using namespace std; #define inf 1<<29 #define nu 10005 #define maxnum 100000 int n,m; int c[nu][nu]; int dist[nu]; int pre[nu]; int book[nu]; void dijkstra(int n,int v){ int i,j; memset(book,0,sizeof(book)); for(i=1;i<=n;i++){ dist[i]=c[v][i]; if(dist[i]>maxnum) pre[i]=0; else pre[i]=v; } dist[v]=0; book[v]=1; for(i=1;i<n;i++){ int temp=maxnum; int u=v; for(j=1;j<=n;j++){ if(!book[j]&&dist[j]<temp) u=j,temp=dist[j]; } book[u]=1; for(j=1;j<=n;j++){ if(!book[j]&&c[u][j]<maxnum) { if(dist[j]>dist[u]+c[u][j]){ dist[j]=dist[u]+c[u][j]; pre[j]=u; } } } } for(int i=1;i<=n;i++) cout<<dist[i]<<endl; } void traceback(int v,int i,int pre[]) { cout<<i<<" <--"; i=pre[i]; if(i!=v) traceback(v,i,pre); if(i==v) cout<<i<<endl; } int main() { cin>>n>>m; for(int i=0;i<nu;i++) for(int j=0;j<nu;j++) if(i!=j) c[i][j]=c[j][i]=maxnum; else c[i][j]=0; for(int i=1;i<=m;i++){ int x,y,z; cin>>x>>y>>z; c[x][y]=c[y][x]=z; } dijkstra(n,2); traceback(2,4,pre); return 0; }