圖論spa
1.基本概念3d
2.圖的儲存code
3.路徑blog
4.自由樹排序
5.有根樹和二叉樹class
6.圖的遍歷二叉樹
7.連通遍歷
8.拓撲排序方法
9.歐拉路徑im
10.最短路
(1)Dijkstra
void dijkstra(int x) { for (int i = 1; i <= n; i++) dis[i] = a[x][i]; dis[x] = 1; f[x] = 1; for (int i = 1; i <= n; i++) { minn = 0; for (int j = 1; j <= n; j++) if (f[j] == 0 && dis[j] > minn) { k = j; minn = dis[j]; } f[k] = 1; if (k == y) break; for (int j = 1; j <= n; j++) if(f[j] == 0 && dis[k] * a[k][j] > dis[j]) dis[j] = dis[k] * a[k][j]; } }
(2)Bellman-Ford
不斷在最短路中加邊
時間複雜度:O(VE)
for (int i = n; i; --i) for (int j = n; j; --j) dis[v[j]] = min(dis[v[j]], dis[u[j]] + w[j]);
(3)Folyd
能夠看做DP,同時求出每點對間的最短路
時間複雜度:O(n3)
for (int k = 1; k <= n; ++k) for (int i = 1; i <= n; ++i) for (int j = 1; j <= n; ++j) dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
(4)SPFA
雖然老師沒講,但我日常都寫這個。。。
void spfa(int x) { for (int i = 1; i <= n; ++i) dis[i] = MAXN, vis[i] = 0; dis[x] = 0; vis[x] = 1; q.push(x); while (!q.empty()) { int y = q.front(); q.pop(); vis[y] = 0; for (int i = head[y]; i; i = net[i]) { int t = to[i]; if (dis[t] > dis[y] + cap[i]) { dis[t] = dis[y] + cap[i]; if (!vis[t]) vis[t] = 1, q.push(t); } } } }
(5)Johnson重賦權
(6)應用:差分約束系統
11.強連通份量
12.邊雙連通份量
13.點雙連通份量
14.最小生成樹MST
(1)MST基本定理
(2)MST求解方法
//其餘兩個不會寫qwq //這是kruskal struct nond { int u, v, w; }e[M]; int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); } bool cmp(nond x, nond y) { return x.w < y.w; } void kruskal() { sort(e+1, e+k+1, cmp); for (int i = 1; i <= k; ++i) { int x = find(e[i].u), y = find(e[i].v); if (x == y) continue; fa[x] = y; ++tot; sum += e[i].w; if (tot == n - 1) break; } return ; }
(3)MST的性質
15.最近公共祖先 LCA
(1)定義 給定兩點 u 和 v ,lca( u, v ) 即爲兩點全部公共祖先中深度最深的一個
(2)求法