您的位置:首页 > 其它

二分图强连通分量 tarjan 模板

2016-03-14 20:36 309 查看
#include<iostream>

#include<string.h>

#include<stdio.h>

#include<vector>

#define maxx 200000

using namespace std;

int a,b,c,d,n,m;

int cnt,fail,biao;

//cnt是每个强连通分量的编号

//fail是栈sta的指针

//biao用于给节点编号

int sta[maxx],belong[maxx],dnf[maxx],low[maxx];

//sta是栈

//belong[i]代表节点i所在的强连通分量编号

//dnf是每个节点的编号

//low其实我也不知道是啥,只要懂他的作用就ok

bool insta[maxx];//节点是否在栈中

vector<int> lin[maxx];//图

int tarjan(int i)

{

        int j;

        dnf[i]=low[i]=++biao;

        sta[++fail]=i;

        insta[i]=true;//编号并入栈

        for (unsigned k=0;k<lin[i].size();k++)

        {

                j=lin[i][k];

                if (dnf[j]==0)    //如果子节点没有编号

                {

                        tarjan(j);

                        low[i]=min(low[i],low[j]);//父亲节点low值是其子节点中low的最小值

                }

                else if (insta[j] && dnf[j]<low[i])

                        low[i]=dnf[j];   //好吧这句我不知道为啥,问了老师来补充

        }

        if (low[i]==dnf[i])//如果形成了一个环,即形成了一个强连通分量,出栈,更新belong数组

        {

                cnt++;

                do    //不会这一句的童鞋不要乱改这里,否则可能会错

                {

                        j=sta[fail--];

                        belong[j]=cnt;

                        insta[j]=0;

                }

                while(i!=j);

        }

}

int solve()

{

        for (int i=1;i<=n;i++)//初始化

        {

                vis[i]=0;

                insta[i]=false;

                sta[i]=0;

                belong[i]=0;

                dnf[i]=0;

                low[i]=0;

        }

        for (int i=1;i<=n;i++)

                if (dnf[i]==0)    //图可能不连通

                        tarjan(i);

}

int main()

    {

        n=6;

        lin[1].push_back(3);

        lin[1].push_back(2);

        lin[2].push_back(4);

        lin[3].push_back(5);

        lin[3].push_back(4);

        lin[4].push_back(1);

        lin[4].push_back(6);

        lin[5].push_back(6);

        solve();

        for(int i=1;i<=n;i++)

            cout<<belong[i]<<" ";

        cout<<endl;

        return 0;

    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: