第三章 搜索与图论 【完结】
以下總結(jié)摘自y總
目錄
- DFS和BFS
- 樹(shù)與圖的存儲(chǔ)
- 樹(shù)與圖的遍歷
- 拓?fù)渑判?/li>
- 樸素dijkstra算法
- 堆優(yōu)化版dijkstra
- Bellman-Ford算法
- spfa 算法(隊(duì)列優(yōu)化的Bellman-Ford算法)
- spfa判斷圖中是否存在負(fù)環(huán)
- floyd算法
- 樸素版prim算法
- Kruskal算法
- 染色法判別二分圖
- 匈牙利算法 (二分圖匹配)
DFS和BFS
842. 排列數(shù)字
843. n-皇后問(wèn)題
844. 走迷宮
845. 八數(shù)碼
樹(shù)與圖的存儲(chǔ)
樹(shù)是一種特殊的圖,與圖的存儲(chǔ)方式相同。
對(duì)于無(wú)向圖中的邊ab,存儲(chǔ)兩條有向邊a->b, b->a。
因此我們可以只考慮有向圖的存儲(chǔ)。
(1) 鄰接矩陣:g[a][ b ] 存儲(chǔ)邊a->b
(2) 鄰接表:
樹(shù)與圖的遍歷
時(shí)間復(fù)雜度 O(n+m), n 表示點(diǎn)數(shù),m 表示邊數(shù)
(1) 深度優(yōu)先遍歷 —— 模板題 AcWing 846. 樹(shù)的重心
(2) 寬度優(yōu)先遍歷 —— 模板題 AcWing 847. 圖中點(diǎn)的層次
queue<int> q; st[1] = true; // 表示1號(hào)點(diǎn)已經(jīng)被遍歷過(guò) q.push(1);while (q.size()) {int t = q.front();q.pop();for (int i = h[t]; i != -1; i = ne[i]){int j = e[i];if (!st[j]){st[j] = true; // 表示點(diǎn)j已經(jīng)被遍歷過(guò)q.push(j);}} }拓?fù)渑判?/h1>
模板題 AcWing 848. 有向圖的拓?fù)湫蛄?br /> 時(shí)間復(fù)雜度 O(n+m), n 表示點(diǎn)數(shù),m 表示邊數(shù)
bool topsort() {int hh = 0, tt = -1;// d[i] 存儲(chǔ)點(diǎn)i的入度for (int i = 1; i <= n; i ++ )if (!d[i])q[ ++ tt] = i;while (hh <= tt){int t = q[hh ++ ];for (int i = h[t]; i != -1; i = ne[i]){int j = e[i];if (-- d[j] == 0)q[ ++ tt] = j;}}// 如果所有點(diǎn)都入隊(duì)了,說(shuō)明存在拓?fù)湫蛄?#xff1b;否則不存在拓?fù)湫蛄小?/span>return tt == n - 1; }樸素dijkstra算法
模板題 AcWing 849. Dijkstra求最短路 I
時(shí)間復(fù)雜是 O(n2+m), n表示點(diǎn)數(shù),m 表示邊數(shù)
int g[N][N]; // 存儲(chǔ)每條邊 int dist[N]; // 存儲(chǔ)1號(hào)點(diǎn)到每個(gè)點(diǎn)的最短距離 bool st[N]; // 存儲(chǔ)每個(gè)點(diǎn)的最短路是否已經(jīng)確定// 求1號(hào)點(diǎn)到n號(hào)點(diǎn)的最短路,如果不存在則返回-1 int dijkstra() {memset(dist, 0x3f, sizeof dist);dist[1] = 0;for (int i = 0; i < n - 1; i ++ ){int t = -1; // 在還未確定最短路的點(diǎn)中,尋找距離最小的點(diǎn)for (int j = 1; j <= n; j ++ )if (!st[j] && (t == -1 || dist[t] > dist[j]))t = j;// 用t更新其他點(diǎn)的距離for (int j = 1; j <= n; j ++ )dist[j] = min(dist[j], dist[t] + g[t][j]);st[t] = true;}if (dist[n] == 0x3f3f3f3f) return -1;return dist[n]; }堆優(yōu)化版dijkstra
模板題 AcWing 850. Dijkstra求最短路 II
時(shí)間復(fù)雜度 O(mlogn), n 表示點(diǎn)數(shù),m 表示邊數(shù)
Bellman-Ford算法
模板題 AcWing 853. 有邊數(shù)限制的最短路
時(shí)間復(fù)雜度 O(nm), n 表示點(diǎn)數(shù),m 表示邊數(shù)
上圖摘自小呆呆大神 :https://www.acwing.com/solution/content/6320/
backup就相當(dāng)于,我們bfs()四個(gè)方向枚舉的時(shí)候,是用當(dāng)前點(diǎn)枚舉的,
不能走一個(gè)方向后,用新的點(diǎn)接著串聯(lián)枚舉。
spfa 算法(隊(duì)列優(yōu)化的Bellman-Ford算法)
模板題 AcWing 851. spfa求最短路
時(shí)間復(fù)雜度 平均情況下 O(m),最壞情況下 O(nm), n 表示點(diǎn)數(shù),m 表示邊數(shù)
Bellman_ford算法會(huì)遍歷所有的邊,但是有很多的邊遍歷了其實(shí)沒(méi)有什么意義,
我們只用遍歷那些到源點(diǎn)距離變小的點(diǎn)所連接的邊即可,
只有當(dāng)一個(gè)點(diǎn)的前驅(qū)結(jié)點(diǎn)更新了,該節(jié)點(diǎn)才會(huì)得到更新;
因此考慮到這一點(diǎn),我們將創(chuàng)建一個(gè)隊(duì)列每一次加入距離被更新的結(jié)點(diǎn)。
上圖摘自:
小呆呆:https://www.acwing.com/solution/content/6325/
orzorz: https://www.acwing.com/solution/content/9306/
spfa判斷圖中是否存在負(fù)環(huán)
模板題 AcWing 852. spfa判斷負(fù)環(huán)
時(shí)間復(fù)雜度是 O(nm), n 表示點(diǎn)數(shù),m 表示邊數(shù)
floyd算法
模板題 AcWing 854. Floyd求最短路
時(shí)間復(fù)雜度是 O(n3), n 表示點(diǎn)數(shù)
摘自:小呆呆 https://www.acwing.com/solution/content/6337/
樸素版prim算法
模板題 AcWing 858. Prim算法求最小生成樹(shù)
時(shí)間復(fù)雜度是 O(n2+m), n 表示點(diǎn)數(shù),m 表示邊數(shù)
Kruskal算法
模板題 AcWing 859. Kruskal算法求最小生成樹(shù)
時(shí)間復(fù)雜度是 O(mlogm), n 表示點(diǎn)數(shù),m 表示邊數(shù)
染色法判別二分圖
模板題 AcWing 860. 染色法判定二分圖
時(shí)間復(fù)雜度是 O(n+m), n 表示點(diǎn)數(shù),m 表示邊數(shù)
匈牙利算法 (二分圖匹配)
模板題 AcWing 861. 二分圖的最大匹配
時(shí)間復(fù)雜度是 O(nm), n 表示點(diǎn)數(shù),m 表示邊數(shù)
總結(jié)
以上是生活随笔為你收集整理的第三章 搜索与图论 【完结】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【PAT乙级】1020 月饼 (25 分
- 下一篇: 第五讲 动态规划