Brine
A certain person trying to make his way in the universe.
22527 鄭竣陽
Brine
BrineTW#7355
Index
Connectivity
vector<int> low(vC);
vector<int> preorder(vC);
vector<bool> isCutVertex(vC);
int counter = 0;
function<void(int, int)> dfs = [&](int u, int last) {
low[u] = preorder[u] = ++counter;
int child = 0;
for (auto& v: graph[u]) {
if (v == last) continue;
if (preorder[v]) { // is back edge
low[u] = min(low[u], preorder[v]);
} else {
dfs(v, u);
if (last >= 0 && low[v] >= preorder[u]) {
isCutVertex[u] = true;
}
child++;
low[u] = min(low[u], low[v]);
}
}
if (last < 0 && child > 1) isCutVertex[u] = true;
};
dfs(0, -1);
vector<int> low(vC);
vector<int> order(vC);
set<pii> isBridge;
int counter = 0;
function<void(int, int)> dfs = [&](int current, int last) {
low[current] = order[current] = ++counter;
for (auto& v: graph[current]) {
if (v == last) continue;
if (order[v]) { // is back edge
low[current] = min(low[current], order[v]);
// a back edge always forms a cycle
} else {
dfs(v, current);
low[current] = min(low[current], low[v]);
if (low[v] > order[current]) {
isBridge.insert({current, v});
}
}
}
};
dfs(0, -1);
Components
struct Edge {
int a, b;
Edge(int u = -1, int v = -1): a(u), b(v) {}
};
vector< vector<int> > graph;
vector<int> low, preorder;
vector<int> isCutVertex;
stack<Edge> s;
vector<int> bccId;
vector< vector<int> > bcc;
int counter = 0;
int bccCounter = 0;
void dfs(int u, int p) {
low[u] = preorder[u] = ++counter;
int child = 0;
for (auto& v: graph[u]) {
Edge e(u, v);
if (v == p) continue;
s.push(e);
if (preorder[v]) {
low[u] = min(low[u], preorder[v]);
continue;
}
child++;
dfs(v, u);
low[u] = min(low[u], low[v]);
if (low[v] >= preorder[u]) {
isCutVertex[u] = 1;
++bccCounter;
Edge temp;
do {
temp = s.top(), s.pop();
if (bccId[temp.a] != bccCounter) bcc[bccCounter].push_back(temp.a);
if (bccId[temp.b] != bccCounter) bcc[bccCounter].push_back(temp.b);
bccId[temp.a] = bccId[temp.b] = bccCounter;
} while (temp.a != u || temp.b != v);
}
}
if (p <= 0 && child == 1) {
isCutVertex[u] = 0;
}
}
vector< vector<int> > graph;
vector<int> low, preorder;
stack<int> s;
vector<int> bccId;
vector< vector<int> > bcc;
int counter = 0;
int bccCounter = 0;
void dfs(int u, int p) {
low[u] = preorder[u] = ++counter;
s.push(u);
for (auto& v: graph[u]) {
if (v == p) continue;
if (preorder[v]) {
low[u] = min(low[u], preorder[v]);
continue;
}
dfs(v, u);
low[u] = min(low[u], low[v]);
if (low[v] > preorder[u]) {
++bccCounter;
int w;
do {
w = s.top(), s.pop();
bccId[w] = bccCounter;
} while (w != u);
}
}
if (p < 0) {
++bccCounter;
int w;
while (!s.empty()) {
w = s.top(), s.pop();
bccId[w] = bccCounter;
}
}
}
#include <bits/stdc++.h>
using namespace std;
vector<int> tarjan(vector< vector<int> >& graph) {
vector<int> preorder(graph.size());
vector<int> low(graph.size());
vector<int> scc(graph.size());
stack<int> s;
int counter = 0;
int sccId = 0;
function<void(int)> dfs = [&](int u) {
preorder[u] = low[u] = ++counter;
s.push(u);
for (auto& v: graph[u]) {
if (scc[v]) continue;
if (preorder[v]) low[u] = min(low[u], preorder[v]);
if (!preorder[v]) {
dfs(v);
low[u] = min(low[u], low[v]);
}
}
if (low[u] == preorder[u]) {
++sccId;
int v;
do {
v = s.top(), s.pop();
scc[v] = sccId;
} while (u != v);
}
};
for (int i = 0; i < graph.size(); i++) if (!preorder[i]) dfs(i);
return scc;
}
void dfs(int current, vector<int>& postorder, vector<bool>& visited, vector< vector<int> >& graph) {
visited[current] = 1;
for (auto& v: graph[current]) {
if (visited[v]) continue;
dfs(v, postorder, visited, graph);
}
postorder.push_back(current);
}
void sfd(int current, vector<int>& scc, const int id, vector< vector<int> >& hparg) {
scc[current] = id;
for (auto& v: hparg[current]) {
if (scc[v]) continue;
sfd(v, scc, id, hparg);
}
}
vector<int> kosaraju(vector< vector<int> >& graph) {
vector<bool> visited(graph.size());
vector<int> postorder;
postorder.reserve(graph.size());
function<void(int)> dfs = [&](int u) {
if (visited[u]) return;
for (auto& v: graph[u]) {
visited[v] = true;
dfs(v);
}
postorder.push_back(u);
};
for (int u = 0; u < graph.size(); u++) dfs(u);
vector< vector<int> > hparg(graph.size());
for (int u = 0; u < graph.size(); u++) {
for (auto& v: graph[u]) hparg[v].push_back(u);
}
vector<int> scc(graph.size());
int sccCounter = 0;
function<void(int)> sfd = [&](int u) {
scc[u] = sccCounter;
for (auto& v: hparg[u]) {
if (scc[v]) continue;
sfd(v);
}
};
reverse(postorder.begin(), postorder.end());
for (auto& u: postorder) {
if (!scc[u]) ++sccCounter, sfd(u);
}
return scc;
}
沒了
By Brine
演算法[18] 連通性、連通分量