-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathgraph_bridges.cpp
More file actions
98 lines (82 loc) · 2.24 KB
/
graph_bridges.cpp
File metadata and controls
98 lines (82 loc) · 2.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
template<int maxv>
struct BridgesFinder {
typedef UnweighedGraph<maxv, false> Graph;
BridgesFinder(const Graph& _g) : g(_g) {}
vector<pair<int, int>> findBridges() {
for (int v = 0; v < maxv; ++v)
if (!tin[v])
dfs(v, -1);
return bridges;
}
private:
void addBridge(int v, int u) {
if (v > u)
swap(v, u);
bridges.push_back(make_pair(v, u));
}
void dfs(int v, int p) {
static int number = 1;
tin[v] = tout[v] = number++;
for (const int u : g.g[v]) {
if (!tin[u]) {
dfs(u, v);
tout[v] = min(tout[v], tout[u]);
if (tout[u] > tin[v])
addBridge(v, u);
} else if (u != p) {
tout[v] = min(tout[v], tin[u]);
}
}
}
// input
const Graph g;
// temporary
int tin[maxv], tout[maxv];
// output
vector<pair<int, int>> bridges;
};
template<int maxv>
struct BridgeCuts {
typedef UnweighedGraph<maxv, false> Graph;
BridgeCuts(const Graph& g) : graph(g) {
memset(visited, 0, sizeof(visited));
memset(block, 0, sizeof(block));
}
Graph run() {
vector<pair<int, int>> bs = BridgesFinder<maxv>(graph).findBridges();
for (pair<int, int> e : bs)
bridges.insert(e);
int blocks_count = 0;
for (int v = 0; v < maxv; ++v)
if (!visited[v])
dfs(v, blocks_count++);
Graph result;
for (auto edge : bridges) {
const int ba = block[edge.first];
const int bb = block[edge.second];
result.addEdge(ba, bb);
}
return result;
}
private:
void dfs(int v, int bid) {
visited[v] = true;
block[v] = bid;
for (int u : graph.g[v]) {
if (visited[u] || hasBridge(v, u))
continue;
dfs(u, bid);
}
}
bool hasBridge(int v, int u) {
if (v > u)
swap(v, u);
return bridges.count(make_pair(v, u));
}
// input
const Graph graph;
// temporary
bool visited[maxv];
int block[maxv]; // map: vertex -> block id
set<pair<int, int>> bridges;
};