匯思學 18國慶 圖論
阿新 • • 發佈:2018-10-04
for 賦權 back div 國慶 同時 ccf net 復雜
圖論
1.基本概念
2.圖的儲存
3.路徑
4.自由樹
5.有根樹和二叉樹
6.圖的遍歷
7.連通
8.拓撲排序
9.歐拉路徑
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)求法
匯思學 18國慶 圖論