Dijkstra算法
最终版本
vector<int> pre[maxn];void Dijkstra(int s){ fill(d, d + maxn, inf); d[s] = 0 for(int i = 0; i < n; i++){ int u = -1, min = inf; for(int j = 0; j < n; j++){ if(vis[j] == false && d[j] < min){ u = j; min = d[j]; } } if(u == -1) return; vis[u] = true; for(int v = 0; v < n; v++){ if(vis[v] == false && G[u][v] != inf){ if(G[u][v] + d[u] < d[v]){ pre[v].clear(); pre[v].push_back(u); d[v] = d[u] + G[u][v]; } else if(d[v] == d[u] + G[u][v]){ pre[v].push_back(u); } } } }}
伪代码
Dijkstra(G, d[], s){ for(循环n次){ u = 使d[u]最小的还未访问的顶点的标号; 记u已经被访问; for(从u出发能到达的所有顶点v){ if(v未被访问 && 以u为中介点使s到顶点v的最短距离d[v]最优){ 优化d[v]; } } }}
邻接矩阵版
const int maxn = 1000;const int INF = 0x3fffffff;int n, G[maxn][maxn];int d[maxn];bool vis[maxn] = {false};void Dijkstra(int s){ fill(d, d + maxn, INF); d[s] = 0; for(int i = 0; i < n;i ++){ //找到未被访问中最小的d[u] int u = -1, min = INF; for(int j = 0; j < n; j++){ if(vis[j] == false && d[j] < min){ u = j; min = d[j]; } } if(u == -1) return;//剩下的都不连通 vis[u] = true; //更新距离 for(int v = 0; v < n; v++){ if(vis[v] == false && G[u][v] != INF && d[u] + G[u][v] < d[v]){ d[v] = d[u] + G[u][v]; } } }}
邻接表版
struct Node{ int v, dis;};vector<Node> Adj[maxn];int n;int d[maxn];//到达各点的最小路径长度bool vis[maxn] = {false};void Dijkstra(int s){ fill(d, d + maxn, INF); d[s] = 0; //找距离最小的 for(int i = 0; i < n; i++){ int u = -1, min = INF; for(int j = 0; j < n; j++){ if(vis[j] == false && d[j] < min){ u = j; min = d[j]; } } } if(u == -1) return; vis[u] = true; //只有这部分不同 for(int j = 0; j < Adj[u].size(); j++){ int v = Adj[u][j].v; if(vis[v] == false && d[u] + Adj[u][j].dis < d[v]){ d[v] = d[u] + Adj[u][j]; } }}