贪心问题之——Dijkstra最短路
关于Dijkstra最短路,其实就是贪心问题,找到原点到各个点的最小值。并且借助最短路找最短路。接下来是代码
#include<bits/stdc++.h> using namespace std; const int INF=1e7; int disk[100],mapp[100][100]; int n,m,st; bool flag[100]; void dijs(int u) { for(int i=1;i<=n;i++){ ///disk为最短路的集,flag判断是否经历 disk[i]=mapp[u][i]; flag[i]=false; } disk[u]=0; flag[u]=true; for(int i=1;i<=n;i++){ int temp=u,cheat=INF; for(int k=1;k<=n;k++) if(disk[k]<cheat&&flag[k]==false){ temp=k; cheat=disk[k]; ///在未入队的集合里面找出最小,于是借助最短路,找其它路。 } if(temp==u) return ; ///判断是否经历 flag[temp]=true; ///入队,借助最短路,找最短路 for(int k=1;k<=n;k++){ if(flag[k]==false) if(disk[k]>disk[temp]+mapp[temp][k]) ///判断是否为最短路 disk[k]=disk[temp]+mapp[temp][k]; } } } int main() { cin >> n >> m;///n表示城市个数,m表示道路条数 for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) mapp[i][j]=INF;///初始化地图 for(int i=1;i<=m;i++){ int v,u,w; cin >> v >> u >> w; mapp[v][u]=min(mapp[v][u],w);///为地图带权赋值 } int st;///输入起始位置 cin >> st; dijs(st); return 0; }
其实,只需要在过程中添加前驱,就可以输出最短路要经过的城市。
#include<bits/stdc++.h> using namespace std; const int INF=1e7; int disk[100],mapp[100][100],p[100];///添加前驱p int n,m,st; bool flag[100]; void dijs(int u) { for(int i=1;i<=n;i++){ ///disk为最短路的集,flag判断是否经历 disk[i]=mapp[u][i]; flag[i]=false; if(disk[i]!=INF) p[i]=u; else p[i]=-1; ///初始化前驱 } disk[u]=0; flag[u]=true; for(int i=1;i<=n;i++){ int temp=u,cheat=INF; for(int k=1;k<=n;k++) if(disk[k]<cheat&&flag[k]==false){ temp=k; cheat=disk[k]; } if(temp==u) return ; ///判断是否经历 flag[temp]=true; ///入队,借助最短路,找最短路 for(int k=1;k<=n;k++){ if(flag[k]==false) if(disk[k]>disk[temp]+mapp[temp][k]){ ///判断是否为最短路 disk[k]=disk[temp]+mapp[temp][k]; p[k]=temp; ///使前驱指向借来的最短路 } } } } void findpath(int u) { int ok; stack<int>s; ///利用栈输出前驱,即可输出最短路 cout << "Begin city: " << u << endl; for(int i=1;i<=n;i++){ ok=p[i]; while(ok!=-1){ s.push(ok); ok=p[ok]; } cout << "The shortest way to "<< i << ":"; while(!s.empty()){ cout <<s.top() << "--"; s.pop(); } cout << i << " ; The shortest way:" << disk[i] << endl; } } int main() { cout << "Enter the number of cities n and number of roads :"; cin >> n >> m;///n表示城市个数,m表示道路条数 for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) mapp[i][j]=INF;///初始化地图 cout << "Enter " << m << " roads:" << endl; for(int i=1;i<=m;i++){ int v,u,w; cin >> v >> u >> w; mapp[v][u]=min(mapp[v][u],w);///为地图带权赋值 } int st;///输入起始位置 cout << "Enter starting point: "; cin >> st; dijs(st); findpath(st); return 0; }