/** * 图的强连通分解——Tarjan算法 **/
class Tarjan {
public:
Tarjan(vector<vector<int> >& g) : g(g), t(0) {}
void decompose() {
unordered_set<int> visited;
for (int s = 0; s < g.size(); ++s) {
if (visited.count(s) == 0) {
tarjan(visited, s);
}
}
for (auto ele_vec : components) {
for (auto ele : ele_vec) cout<<ele<<",";
cout<<endl;
}
}
private:
void tarjan(unordered_set<int>& visited, int s) {
touch[s] = t;
backup[s] = t;
t++;
visited.insert(s);
stack_ele.insert(s);
S.push(s);
for (int v = 0; v < g.size(); ++v) {
if (g[s][v] > 0 && visited.count(v) == 0) {
tarjan(visited, v);
backup[s] = min(backup[s], backup[v]);
} else {
if (g[s][v] > 0 && stack_ele.count(v))
backup[s] = min(backup[s], touch[v]);
}
}
if (backup[s] == touch[s]) {
int u = -1;
vector<int> ret_ele;
do {
u = S.top();S.pop();
ret_ele.push_back(u);
stack_ele.erase(u);
} while(s != u);
components.push_back(ret_ele);
}
}
int t;
unordered_map<int, int> touch;
unordered_map<int, int> backup;
vector<vector<int> >& g;
stack<int> S;
unordered_set<int> stack_ele;
vector<vector<int> > components;
};