强连通分量

来源:互联网 发布:618淘宝也买酒 编辑:程序博客网 时间:2024/04/30 03:43

tarjan算法

void tarjanOne(vector<vector<int>> &links,vector<int> &marks,int u,int &time,vector<int> &DFN,vector<int> &LOW,stack<int> &Stack,set<int> &Set){    //Stack为栈 Set为栈中的元素    //u当前节点    //DFN表示访问当前结点u的时间    //LOW表示u所在的连通分量的最早访问时间    DFN[u] = LOW[u] = ++time;    Stack.push(u);    Set.insert(u);    int v;    for (size_t i = 0; i < links[u].size(); i++)    {        v = links[u][i];//取出相连节点        if (!DFN[v])//v节点未访问过        {            tarjanOne(links, marks, v, time, DFN, LOW, Stack,Set);            LOW[u] = min(LOW[u],LOW[v]);        }        else if (Set.find(v) != Set.end())//v在栈中        {            LOW[u] = min(LOW[u],LOW[v]);//min(LOW[u],DFN[v])不影响最后结果        }    }    //此时u已经没有可以访问的其他节点了    if (DFN[u] == LOW[u])    {        //将与u在一个连通分量内的节点都弹出(包括u)        do        {            v = Stack.top();            Stack.pop();            Set.erase(v);            marks[v] = u;//将所有在同一个连通分量里的点都标记为u        } while (u!=v);    }}vector<int> tarjanAll(vector<vector<int>> &links){    int N = links.size();    vector<int> marks(N, -1);    //存在多个连通分量的情况    for (size_t i = 0; i < N; i++)    {        if (marks[i] == -1)        {            int time = 0;            vector<int> DFN(N,0);            vector<int> LOW(N,0);            stack<int> Stack;            set<int> Set;            tarjanOne(links,marks,i,time,DFN,LOW,Stack,Set);        }    }    return marks;}
0 0
原创粉丝点击