1. 程式人生 > >有向圖的強連通分解--Kosaraju演算法

有向圖的強連通分解--Kosaraju演算法

/**
 * 圖的強連通分解——Kosaraju演算法
 **/
class Kosaraju {
public:
    Kosaraju(vector<vector<int> >& g) : g(g), t(0) {}
    void decompose() {
        vector<int> vertice_order;
        for (int i = 0; i < g.size(); ++i) vertice_order.push_back(i);
        this->dfs(vertice_order);
        this
->transpose(); vertice_order = this->get_vertice_order_by_f(); t = 0; b.clear(); f.clear(); visited.clear(); auto ret = this->dfs(vertice_order); for (auto ele_ret : ret) { for (auto ele : ele_ret) { cout<<ele<<","
; } cout<<endl; } cout<<endl; } private: void transpose() { for (int i = 0; i < g.size(); ++i) { for (int j = i + 1; j < g[i].size(); ++j) { swap(g[i][j], g[j][i]); } } } vector
<int>
get_vertice_order_by_f() { multimap<int, int> order; for (auto ele : f) { order.insert(make_pair(ele.second, ele.first)); } vector<int> ret; for (auto ele_r = order.rbegin(); ele_r != order.rend(); ++ele_r) ret.push_back(ele_r->second); return ret; } vector<vector<int> > dfs(vector<int>& vertice_order) { vector<vector<int> > ret; for (auto vertice : vertice_order) { if (visited.count(vertice) == 0) { vector<int> ret_ele; dfs_inner(vertice, ret_ele); ret.push_back(ret_ele); } } return ret; } void dfs_inner(int s, vector<int>& ret) { b[s] = t++; visited.insert(s); ret.push_back(s); for (int adj = 0; adj < g.size(); ++adj) { if (visited.count(adj) == 0 && g[s][adj] > 0) { dfs_inner(adj, ret); } } f[s] = t++; } private: int t; unordered_map<int, int> b; unordered_map<int, int> f; unordered_set<int> visited; vector<vector<int> >& g; };