20506王大宇
我的slides: https://slides.com/yeedrag
正常人看到二分圖:
給你一個帶權的圖,問你從點A到其他點的最短距離
d(0,3) = 5
d(1,4) = 3
d(2,3) = 3
看V加上兩者連接的邊權,和目前的最短距離比如果比較
近就更新他!
4
1
2
5
8
10
2
3
6
a
b
c
d
e
f
a
b
c
d
e
f
a | b | c | d | e | f |
---|---|---|---|---|---|
0 | 4 | 2 | inf | inf | inf |
0 | 3 | 2 | 10 | 12 | inf |
0 | 3 | 2 | 8 | 12 | inf |
0 | 3 | 2 | 8 | 10 | 11 |
0 | 3 | 2 | 8 | 10 | 11 |
dist:
int dis[MAXN];
//點距離起始點的距離
vector<pair<int,int>> graph[MAXN];
//存圖,使用的是相鄰串列的作法,和講義上存圖的方法不太一樣。可以參考我的其他slides
//pair裡面存[邊權,點索引值]
void dijkstra_algorithm(int start){
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> pq;
//priority_queue為優先佇列,以上方寫法為例,pq.top()永遠是最小的值
bool visited[n+1] = {false};//是否造訪過
for(int i=1;i<=n;i++) dis[i] = INF;//假設所有點距離起始點距離無限
dis[start] = 0;//起始點距離起始點是0
pq.push({0,start});//把起始點放進優先佇列內
while(pq.size()){//當還有點沒被造訪過
auto [w,v] = pq.top();//拿取目前未造訪,離起始點最近的點
pq.pop();//用過了pop掉
if(visited[v]) continue;
visited[v] = 1;
for(auto [w_2,v_2]:graph[v]){
if(w+w_2<dis[v_2]){//鬆弛
dis[v_2] = w+w_2;
pq.push({dis[v_2],v_2});//鬆完的點放入佇列
}
}
}
}