|
1 | 1 | import { CutMap, BridgeMap } from "../types"; |
2 | 2 |
|
3 | | -export function buildBridges( |
| 3 | +export function buildCuts( |
4 | 4 | nodes: string[], |
5 | 5 | adj: Map<string, string[]>, |
6 | 6 | rev: Map<string, string[]>, |
7 | | -): [CutMap, BridgeMap] { |
| 7 | +): CutMap { |
8 | 8 | let depth = new Map<string, number>(); |
9 | 9 | let memo = new Map<string, number>(); |
10 | 10 |
|
@@ -130,5 +130,88 @@ export function buildBridges( |
130 | 130 | } |
131 | 131 | } |
132 | 132 |
|
133 | | - return [cutMap, bridgeMap]; |
| 133 | + return cutMap; |
| 134 | +} |
| 135 | + |
| 136 | +export function buildBridges( |
| 137 | + nodes: string[], |
| 138 | + edges: string[], |
| 139 | +): BridgeMap { |
| 140 | + |
| 141 | + const adjFull = new Map<string, string[]>(); |
| 142 | + |
| 143 | + for (const u of nodes) { |
| 144 | + adjFull.set(u, []); |
| 145 | + } |
| 146 | + |
| 147 | + for (const e of edges) { |
| 148 | + let u = e.split(" ")[0]; |
| 149 | + let v = e.split(" ")[1]; |
| 150 | + adjFull.get(u)!.push(v); |
| 151 | + adjFull.get(v)!.push(u); |
| 152 | + } |
| 153 | + |
| 154 | + let colorMap = new Map<string, number>(); |
| 155 | + |
| 156 | + let color = 0; |
| 157 | + let time = 0; |
| 158 | + |
| 159 | + let dfn = new Map<string, number>(); |
| 160 | + let low = new Map<string, number>(); |
| 161 | + let stack: string[] = []; |
| 162 | + |
| 163 | + let bcc = new Map<number, string[]>(); |
| 164 | + |
| 165 | + const dfs = (u: string, parent: string | null): void => { |
| 166 | + time++; |
| 167 | + dfn.set(u, time); |
| 168 | + low.set(u, time); |
| 169 | + stack.push(u); |
| 170 | + |
| 171 | + for (const v of adjFull.get(u)!) { |
| 172 | + if (v === parent) { |
| 173 | + parent = null; |
| 174 | + continue; |
| 175 | + } else if (!dfn.has(v)) { |
| 176 | + dfs(v, u); |
| 177 | + low.set(u, Math.min(low.get(u)!, low.get(v)!)); |
| 178 | + } else { |
| 179 | + low.set(u, Math.min(low.get(u)!, dfn.get(v)!)); |
| 180 | + } |
| 181 | + } |
| 182 | + |
| 183 | + if (low.get(u) === dfn.get(u)) { |
| 184 | + color ++; |
| 185 | + const component = []; |
| 186 | + let w: string; |
| 187 | + do { |
| 188 | + w = stack.pop()!; |
| 189 | + component.push(w); |
| 190 | + colorMap.set(w, color); |
| 191 | + } while (w !== u); |
| 192 | + bcc.set(color, component); |
| 193 | + } |
| 194 | + }; |
| 195 | + |
| 196 | + for (const u of nodes) { |
| 197 | + if (!dfn.has(u)) { |
| 198 | + dfs(u, null); |
| 199 | + } |
| 200 | + } |
| 201 | + |
| 202 | + let bridgeMap: BridgeMap = new Map<string, boolean>(); |
| 203 | + |
| 204 | + for (const e of edges) { |
| 205 | + let u = e.split(" ")[0]; |
| 206 | + let v = e.split(" ")[1]; |
| 207 | + if (colorMap.get(u) !== colorMap.get(v)) { |
| 208 | + bridgeMap.set([u, v].join(" "), true); |
| 209 | + bridgeMap.set([v, u].join(" "), true); |
| 210 | + } else { |
| 211 | + bridgeMap.set([u, v].join(" "), false); |
| 212 | + bridgeMap.set([v, u].join(" "), false); |
| 213 | + } |
| 214 | + } |
| 215 | + |
| 216 | + return bridgeMap; |
134 | 217 | } |
0 commit comments