從原畫到建模 《英靈神殿》開發者展示“迷霧之地”新武器
阿新 • • 發佈:2022-03-14
樸素Dijkstra--\(O(n^2)\)
題目連結
https://www.acwing.com/problem/content/851/
Ac程式碼
點選檢視程式碼
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 510; int g[N][N]; int n, m; int dist[N]; bool st[N]; int dijkstra(){ memset(dist, 0x3f, sizeof dist); dist[1] = 0; //遍歷所有點 for(int i = 1; i <= n; i ++){ //找出不在集合中的最近的點加入集合 int t = -1; //技巧性寫法 for(int j = 1; j <= n; j ++){ if(!st[j] && (dist[t] > dist[j] || t == -1)){ t = j; } } //用這個點更新其他點的距離 for(int j = 1; j <= n; j ++){ if(dist[j] > dist[t] +g[t][j]){ dist[j] = dist[t] + g[t][j]; } } //將這個點加入集合 st[t] = true; } if(dist[n] == 0x3f3f3f3f) return -1; return dist[n]; } int main() { scanf("%d%d", &n, &m); memset(g, 0x3f, sizeof g); while(m --){ int a, b, c; scanf("%d%d%d", &a, &b, &c); g[a][b] = min(g[a][b], c); } printf("%d\n", dijkstra()); return 0; }
堆優化版的Dijkstra--\(O(mlogn)\)
題目連結
https://www.acwing.com/problem/content/852/
Ac程式碼
點選檢視程式碼
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; typedef pair<int, int> PII; const int N = 2e5 + 10; int n, m; int h[N], e[N], ne[N], w[N], idx; int dist[N]; bool st[N]; void add(int a, int b, int c){ e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++; } int dijkstra(){ memset(dist, 0x3f, sizeof dist); dist[1] = 0; //堆的定義 priority_queue<PII, vector<PII>, greater<PII>> heap; heap.push({0, 1}); while(!heap.empty()){ PII t = heap.top(); heap.pop(); //找到不在集合中的最近的點,將它加入集合 //由於PII預設按照第一維排序,所以PII的第一維存distance int ver = t.second, distance = t.first; if(st[ver]) continue; st[ver] = true; //更新其他所有點的距離 for(int i = h[ver]; i != -1; i = ne[i]){ int j = e[i]; if(dist[j] > distance + w[i]){ dist[j] = distance + w[i]; heap.push({dist[j], j}); } } } if(dist[n] == 0x3f3f3f3f) return -1; return dist[n]; } int main() { scanf("%d%d", &n, &m); memset(h, -1, sizeof h); while(m --){ int a, b, c; scanf("%d%d%d", &a, &b, &c); add(a, b, c); } printf("%d\n", dijkstra()); return 0; }