2

なぜグラフの転置を作成し、2 番目のパスで転置に対して dfs を実行するのでしょうか。正しさの証明http://www.jeffreykarres.com/blog/kosaraju/をオンラインで読んでみましたが、理解できませんでした。これを行うには、理解しやすい代替アプローチがいくつかあります

これはアルゴリズムの私の実装であり、入力として頂点とエッジの数を取り、次に有向エッジを入力として取ります(頂点には0からn-1の番号が付けられます)

#include <bits/stdc++.h>
using namespace std;
void dfsForward(int src , vector<vector<int>> g , vector<bool> &vis, stack<int> &s ){
    vis[src]=true;
    for(int i=0;i<g[src].size();i++){
        if(!vis[g[src][i]])
         dfsForward(g[src][i],g,vis,s);
    }
    s.push(src);
}
void dfsRev(int src , vector<vector<int>> t , vector<bool> &vis, vector<int> &comp,int count ){
    vis[src]=true;
    for(int i=0;i<t[src].size();i++){
        if(!vis[t[src][i]]){
           comp.push_back(t[src][i]);
            dfsRev(t[src][i],t,vis,comp,count);
        }
    }
}
vector<vector<int>> kosaraju(vector<vector<int>> g,vector<vector<int>> t, int n){
    vector<bool> vis(n,false); 
    vector<bool> visRev(n,false); 
    vector<vector<int>> scc; 
    int count=0;
    stack<int> s;
    for(int i=0;i<n;i++){
        if(!vis[i])
         dfsForward(i,g,vis,s);
    }
    while(!s.empty()){
        int temp =s.top();
        s.pop();
        if(!visRev[temp]){
           count++;    
           vector<int> comp;
           comp.push_back(temp);
           dfsRev(temp,t,visRev,comp,count);
           scc.push_back(comp);
        }
    } 
    return scc;
}
int main() {
    int n,e,u,v;
    cin>>n>>e;
    vector<vector<int>> g(n);
    vector<vector<int>> t(n);
    for(int i=0;i<e;i++){
        cin>>u>>v;
        g[u].push_back(v);
        t[v].push_back(u);
    }
    cout<<"components are "<<endl;
    vector<vector<int>> scc = kosaraju(g,t,n);
    for(int i=0;i<scc.size();i++){
        vector<int> arr = scc[i];
        for(int j=0;j<arr.size();j++){ 
            cout<<arr[j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}
4

1 に答える 1