Such like we want to find the path between two nodes in the grpah.
舉個例子 2x2 的魔術方塊
優點
缺點
想自殺才自己寫Linked List
以下是 AdjList 的範例 code :
class Graph {
private:
int num_vertex;
std::vector<int> AdjList;
void DFSUtil(int v, bool visited[]);
public:
Graph():num_vertex(0){}; // construct class with no function parameter, then the vertex will be set to 0
Graph(int N):num_vertex(N){ //construct class with number of vertex
AdjList.resize(num_vertex); //initialize Adjlist
}
void AddEdgeList(int from, int to){
AdjList[from].push_back(to);
}
};
優點
缺點
考慮這張圖,這邊先用 Adjacency List 來做做看。
先發現這是一張 connected undirected graph , 所以我們可以確保任一個 vertex 都至少有一條 edge 與其他 vertex 連接。
如果我們從 A 開始做 BFS,我們可以得到:
Since Graph G is a connected undriected graph, so we can always find the path that connected any two vertexs in this grpah.
我們看看下面這個步驟圖
影片連結:https://www.youtube.com/watch?time_continue=350&v=0u78hx-66Xk&feature=emb_logo
如果我們拿一顆 tree 當做例子,我們可以了解到,BFS 就是 Level-order,而 tree 本身就是一個特殊的圖。
時間複雜度: \(O(VlogV+E)\)
對一個 grpah G = {E, V}
重複下面這件事 V 次,以將所有點加入到最短路徑樹
在實作上我們可以利用 priority_queu 去讓每次在queu 裡面的第一個都是與起點距離最近的 vertex 也就是我們下一次要找pick 的 vertex 。
void Graph::dijkstra(int start){
priority_queue< pair<int, int>, vector< pair<int, int> >, greater< pair<int, int> > > pq;
vector<int> dist{_num_vertex, INF}; // distances as infinite (INF)
//set the first vertex to be 0
pq.push(make_pair(0, start));
dist[start] = 0;
while(!pq.empty()){
int u = pq.top().second;
pq.pop();
for(vector< pair<int, int> >::iterator i = _AdjList[u].begin(); i != _AdjList[u].end(); ++i){
int v = (*i).first;
int weight = (*i).second;
if(dist[v] > dist[u] + weight){
dist[v] = dist[u] + weight;
pq.push(make_pair(dist[u], v));
}
}
}
printf("Vertex Distance from Source\n");
for (int i = 0; i < _num_vertex; ++i)
printf("%d \t\t %d\n", i, dist[i]);
}
影片連結: https://www.youtube.com/watch?v=5GT5hYzjNoo
為了要解決最小(大)生成樹問題,我們有這邊使用三種演算法,Kruskal and Prim,兩種演算法均為Greedy algorithm
一般來說,我們在實作 Kruskal’s algorithm 的時候,我們會利用 Dijont Set 去判斷是否產生 loop
以下是 Pseudo code
MST-KRUSKAL(G,w)
A={}
for each vertex v∈G.V
MAKE-SET(v)
sort G.E by w
for each edge (u,v) ∈G.E
if FIND-SET(u)≠FIND-SET(v)
A=A⋃{(u,v)}
UNION(u,v)
return A
首先我們先來看看這張圖
我們先創建一個 set 包含所有的 edges and vertices in G = {E, V}.
我們先 sort 過所有的 edges 得到
[10, 12, 14, 16, 18, 22, 24, 25, 28]
以及
Set A {()}
Set A { (0,5)}
Set A { (0, 5), (2, 3) }
Set A { (0, 5), (2, 3), (1,6)}
Set A { (0, 5), (2, 3), (1, 6), (1, 2)}
Set A { (0, 5), (2, 3), (1, 6), (1, 2)}
Set A { (0, 5), (2, 3), (1, 6), (1, 2), (3, 4), (4, 5)}
然後我們來看看他的證明
http://www.m98.nthu.edu.tw/~s9822506/Kruskal.pdf
與 Dijkstra's Algorithm 類似,都是透過窮舉去尋找樹上得點,只是 Dijkstra 是找不在樹上,且離根最近的點
5.4 Soll