1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
清除所有点的标号 设dis【start】 = 0, 其他dis【i】 = inf; 循环nodeNUm次{ 在所有未标号节点中,选出dis[]值最小的结点x 给结点x标记 对于从x除法的所有边(x, y)更新d[y] = min(d[y], d[x] + w(x, y)); } */
#include <iostream> #include <cstring> #include <cstdio> #include <queue>
using namespace std;
const int maxNodeNum=110; const int maxEdgeNum=10010;
const int inf=0x3f3f3f3f;
{ if(dis[j]>dis[MinNumber]+mp[MinNumber][j]) { dis[j]=dis[MinNumber]+mp[MinNumber][j];
} }*/
int nodeNum,edgeNum; int mp[maxNodeNum][maxNodeNum]; int dis[maxNodeNum]; int father[maxNodeNum]; bool vis[maxNodeNum];
void dijkstra(int start) { memset(dis,inf,sizeof(dis)); memset(vis,0,sizeof(vis)); for(int i = 0; i < nodeNum; i++){ father[i] = i; } dis[start]=0;
for(int i=1;i<=nodeNum;i++) { int MinNumber = -1,Min=inf; for(int j=1;j<=nodeNum;j++) if(!vis[j] && dis[j]<Min){ Min=dis[j]; MinNumber=j; } if(MinNumber == -1) break; vis[MinNumber]=1; for(int j=1;j<=nodeNum;j++)if(!vis[j] && mp[MinNumber][j] != inf){ dis[j] = min(dis[j], dis[MinNumber] + mp[MinNumber][j]); father[j] = MinNumber; } } }
void printPath(int e) { if(e != father[e]){ printPath(father[e]); cout << "->" << e; } else{ cout << e; } }
int main() { while(cin>>nodeNum>>edgeNum&&(nodeNum||edgeNum)) { int from,to,w; memset(mp,inf,sizeof(mp)); for(int i=1;i<=edgeNum;i++) { cin>>from>>to>>w; if(w<mp[from][to]) mp[from][to]=mp[to][from]=w; } dijkstra(1); cout<<dis[nodeNum]<<endl; printPath(nodeNum); } return 0; }
输入: 5 5 1 2 1 2 3 2 3 5 1 1 4 1 4 5 1
输出: 1->4->5
|