Graph Theory
BY:覺得圖論很難的Yeedrag
應該說接下來兩堂都很難w
嚴格解釋:點的集合加上邊的集合
3
1.入度 (通往這個點的邊數)
2.出度(離開這個點的邊數)
A
B
C
(A,B),(B,C)相鄰且連通
(A,C)(A,C)間則只有連通
btw,如果是有向無環圖(DAG),
可以做拓撲排序(Topological Sort)喔!
可能下學期還啥的會教.jpg
除了根節點外
每個節點都有一個母節點與一或多個子節點
or
邊的數量為\(V-1\)的連通圖
A
B
C
F
G
H
E
D
根節點
葉節點
父節點
子節點
無情開偷學長動畫爽阿刺阿
可以被切為兩個不相連的點集
可以開始正課了! ⁽⁽٩(๑˃̶͈̀ ᗨ ˂̶͈́)۶⁾⁾
建一個\(V*V\)的矩陣,
\((i,j)\)項表示\(i\)跟\(j\)是否相鄰(or存邊權)
1
2
3
4
5
6
1 | 2 | 3 | 4 | 5 | 6 | |
---|---|---|---|---|---|---|
1 | 0 | 1 | 1 | 0 | 0 | 1 |
2 | 1 | 0 | 0 | 0 | 0 | 0 |
3 | 1 | 0 | 0 | 1 | 1 | 0 |
4 | 0 | 0 | 1 | 0 | 0 | 0 |
5 | 0 | 0 | 1 | 0 | 0 | 0 |
6 | 1 | 0 | 0 | 0 | 0 | 0 |
1 | 1,2,6 |
---|---|
2 | 1 |
3 | 1,4,5 |
4 | 3 |
5 | 3 |
6 | 1 |
1
2
3
4
5
6
相鄰矩陣是\(O(V^2)\)
相鄰串列是\(O(V)\)
遍歷:
矩陣是\(O(V^2)\)
串列是\(O(V)\)
是否相鄰:
矩陣:\(O(1)\) , 串列:\(O(V)\)
int graph_1[V][V];
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
int a,b;
cin>>a>>b;
graph[a][b] = 1;
//graph[b][a] = 1;
}
}
vector<int> graph[V];
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
int a,b;
cin>>a>>b;
graph[a].push_back(b);
//graph[b].push_back(a);
}
}
帶權vector就存pair!
BFS/DFS
for(int i=0;i<n;i++){
arr[i]......
}
可以用
for(auto i:arr){
// i is every element
// in the array
}
for(auto &i:arr){
//如果會更動到arr裡的值
//i前面要加&!
}
優先往深的地方一直走!
1
2
3
4
5
6
順序:1->2->3->4->5->6
bool visited[V+1];
void dfs(int v){
visited[v] = true;
/*
做想在遍歷時做的事
*/
for(auto i:graph[v]){
if(!visited[i.first]){
dfs(i.first);
//還沒遇過就dfs下去
} else {
continue;
}
}
}
有先遇到的就先走!
1
2
3
4
5
6
順序:1->2->3->6->4->5
bool visited[V+1];
void bfs(int start){
queue<int> que;
que.push(start)//把第一個點push進queue
visited[start] = true;//已造訪
while(que.size()){//當還有東西時
/*
做你在遍歷時想做的事
*/
for(auto i:graph[que.front()]){
if(!visited[i.first]){
visited[i.first] = true;
que.push(i.first);
}
}
que.pop();
}
}
需要紀錄距離的BFS
BFS的裸題
可以說是遞迴練習的DFS/BFS題目
要回推移下的題目.w.
難度有點高的BFS