booltopsort() { int cnt = 0; queue<int> q; for (int i = 1; i <= n; i++) if (din[i] == 0) { din[i]--; q.push(i); topo.push(i); cnt++; } while(q.size()) { int u = q.front(); q.pop(); for (int i = h[u]; i != -1; i = ne[i]) { int v = e[i]; din[v]--; if (din[v] == 0) { q.push(i); topo.push(i); cnt++; } } } return cnt == n; }
for (int i = 0; i < n - 1; i ++ ) { int u = -1; // 在还未确定最短路的点中,寻找距离最小的点 for (int j = 1; j <= n; j ++ ) if (!st[j] && (u == -1 || dist[u] > dist[j])) u = j;
// 如果第n次迭代仍然会松弛三角不等式,就说明存在一条长度是n+1的最短路径,由抽屉原理,路径中至少存在两个相同的点,说明图中存在负权回路。 for (int i = 0; i < n; i ++ ) { for (int j = 0; j < m; j ++ ) { int a = edges[j].a, b = edges[j].b, w = edges[j].w; if (dist[b] > dist[a] + w) dist[b] = dist[a] + w; } }
if (dist[n] > 0x3f3f3f3f / 2) return-1; return dist[n]; }
while (q.size()) { auto u = q.front(); q.pop(); st[u] = false;
for (int i = h[u]; i != -1; i = ne[i]) { int v = e[i]; if (dist[v] > dist[u] + w[i]) { dist[v] = dist[u] + w[i]; if (!st[v]) // 如果队列中已存在j,则不需要将j重复插入 { q.push(v); st[v] = true; } } } }
if (dist[n] == 0x3f3f3f3f) return-1; return dist[n]; }
floyd算法
考虑到任何一条路径都可以转化为两条更短的路径,所以通过枚举拆分路径的方式维护最短路。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
voidinit() { for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= n; j ++ ) if (i == j) d[i][j] = 0; else d[i][j] = 0x3f3f3f3f; }
// 算法结束后,d[a][b]表示a到b的最短距离 voidfloyd() { for (int k = 1; k <= n; k ++ ) for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= n; j ++ ) d[i][j] = min(d[i][j], d[i][k] + d[k][j]); }
intkruskal() { for (int i = 1; i <= n; i++) p[i] = i; sort(edges + 1, edges + m + 1, [](Edge a, Edge b) -> bool { return a.w < b.w; }); int sum = 0; for (int i = 1; i <= m; i++) { int a = edges[i].a, b = edges[i].b, w = edges[i].w; if (find(a) != find(b)) { add(a, b); sum += w; } } return sum; }
booldfs(int u, int c) { color[u] = c; for (int i = h[u]; i != -1; i = ne[i]) { int v = e[i]; if (!color[v]) { if (!dfs(v, 3 - c)) returnfalse; } elseif (color[v] == c) returnfalse; } returntrue; }
voidbfs(int r) { memset(depth, 0x3f, sizeof(depth)); depth[0] = 0, depth[r] = 1; queue<int> q; q.push(r); while (q.size()) { int u = q.front(); q.pop(); for (int i = h[u]; i != -1; i = ne[i]) { int v = e[i]; if (depth[v] > depth[u] + 1) { depth[v] = depth[u] + 1; q.push(v); fa[v][0] = u; for (int k = 1; fa[v][k - 1]; k++) fa[v][k] = fa[fa[v][k - 1]][k - 1]; } } } }
intlca(int a, int b) { if (depth[a] < depth[b]) swap(a, b); for (int k = K; k >= 0; k--) if (depth[fa[a][k]] >= depth[b]) a = fa[a][k]; if (a == b) return a; for (int k = K; k >= 0; k--) if (fa[a][k] != fa[b][k]) a = fa[a][k], b = fa[b][k]; return fa[a][0]; }