PAT (Advanced Level) Practice Dijkstra 相關題ios
對任意給出的圖 G(V,E) 和 起點 S,終點 T,求 S 到 T 的最短路徑算法
只能處理全部邊權均非負的狀況數組
若出現負數,最好使用 SPFA 算法spa
const int MAXV = 1000; const int INF = 0x3fffffff; int n, G[MAXV][MAXV], d[MAXV], pre[MAXV]; bool vis[MAXV] = {false}; void Dijkstra(int s){ fill(d, d + MAXV, INF); d[s] = 0; for (int i = 0; i < n; i++) pre[i] = i; for (int i = 0; i < n; i++){ int u = -1, MIN = INF; for (int j = 0; j < n; j++){ // 找未訪問結點中 d[] 最小的 if (!vis[j] && d[j] < MIN){ u = j; MIN = d[j]; } } if (u == -1) return; // 找不到 d[u] < INF 點,說明剩下的點與起點 s 不連通 vis[u] = true; for (int v = 0; v < n; v++){ if (!vis[v] && G[u][v] != INF && d[u] + G[u][v] < d[v]){ d[v] = d[u] + G[u][v]; pre[v] = u; } } } } void DFS(int s, intv){ if (v == s){ printf("%d", s); return; } DFS(s,pre[v]); printf(" %d", v); }
第一標尺爲距離指針
如邊的花費code
int cost[MAXV][MAXV], c[MAXV]; fill(c, c + MAXV, INF); c[s] = 0; for (int v = 0; v < n; v++){ if (!vis[v] && G[u][v] != INF){ if (d[u] + G[u][v] == d[v] && c[u] + cost[u][v] < c[v]){ pre[v] = u; c[v] = c[u] + cost[u][v]; } else if (d[u] + G[u][v] < d[v]){ pre[v] = u; d[v] = d[u] + G[u][v]; c[v] = c[u] + cost[u][v]; } } }
如點的權重io
int weight[MAXV], w[MAXV] = {0}; w[s] = weight[s]; for (int v = 0; v < n; v++){ if (!vis[v] && G[u][v] != INF){ if (d[u] + G[u][v] == d[v] && w[u] + weight[v] > w[v]){ pre[v] = u; w[v] = w[u] + weight[v]; } else if (d[u] + G[u][v] < d[v]){ pre[v] = u; d[v] = d[u] + G[u][v]; w[v] = w[u] + weight[v]; } } }
int num[MAXV] = {0}; num[s] = 1; for (int v = 0; v < n; v++){ if (!vis[v] && G[u][v] != INF){ if (d[u] + G[u][v] == d[v]{ pre[v] = u; num[v] += num[u]; } else if (d[u] + G[u][v] < d[v]){ pre[v] = u; d[v] = d[u] + G[u][v]; num[v] = num[u]; } } }
#include<iostream> using namespace std; const int MAXN = 500, INF = 0x3fffffff; int n, s, t, G[MAXN][MAXN], weight[MAXN], d[MAXN], pathnum[MAXN], w[MAXN] = {0}; bool vis[MAXN] = {false}; void Dijkstra(){ fill(d, d + MAXN, INF); d[s] = 0; pathnum[s] = 1; w[s] = weight[s]; for (int i = 0; i < n; i++){ int u = -1, MIN = INF; for (int j = 0; j < n; j++){ if (!vis[j] && d[j] < MIN){ u = j; MIN = d[j]; } } vis[u] = true; for (int v = 0; v < n; v++){ if (!vis[v] && G[u][v] != INF){ if (d[v] == d[u] + G[u][v]){ pathnum[v] += pathnum[u]; if (w[v] < w[u] + weight[v]) w[v] = w[u] + weight[v]; } else if (d[v] > d[u] + G[u][v]){ d[v] = d[u] + G[u][v]; w[v] = w[u] + weight[v]; pathnum[v] = pathnum[u]; } } } } } int main() { int m, u, v, len; scanf("%d%d%d%d", &n, &m, &s, &t); for (int i = 0; i < n; i++) scanf("%d", &weight[i]); fill(G[0], G[0] + MAXN * MAXN, INF); for (int i = 0; i < m; i++){ scanf("%d%d%d", &u, &v, &len); G[u][v] = len; G[v][u] = len; } Dijkstra(); printf("%d %d", pathnum[t], w[t]); return 0; }
fill(G[0], G[0] + MAXN * MAXN, INF)
注意二維數組要取首地址做爲指針類型不能直接用數組名,由於它至關因而一維數組的指針,而參數要求是指針