无重边有向连通图的强连通分量

来源:互联网 发布:抽数字软件在线 编辑:程序博客网 时间:2024/06/05 15:24
#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<stack>using namespace std;int n,m,ntime;//ntime记录dfs访问时间int instack[11000];//标记点是否在栈中int dfn[11000];//节点在dfs过程中的访问序号(也可以叫做开始时间)int low[11000];//从该节点出发dfs过程中该节点下方节点(开始时间大于该节点的开始时间,且由该节点可达的节点)所能到达的最早的节点的开始时间,初始low数组等于dfn数组vector<vector<int> > g;stack<int> st;void tarjan(int u){    int i,v;    dfn[u]=low[u]=ntime++;    st.push(u);    instack[u]=1;    for(i=0;i<g[u].size();i++)//从u出发的每一条边    {        v=g[u][i];        if(dfn[v]==0)//v还没被访问过        {            tarjan(v);            low[u]=min(low[u],low[v]);        }        else if(instack[v])//v在栈中        {            low[u]=min(low[u],dfn[v]);        }    }    if(dfn[u]==low[u])//u是一个强连通分量的根    {        do        {            v=st.top();            st.pop();            instack[v]=0;            printf("%d ",v);//输出属于这个强连通分量的所有的点的编号        }while(u!=v);        printf("\n");    }}int main(){     int i;     while(scanf("%d%d",&n,&m)!=EOF)     {     g.clear();     g.resize(11000);     while(!st.empty()) st.pop();     ntime=1;     memset(instack,0,sizeof(instack));     memset(dfn,0,sizeof(dfn));     memset(low,0,sizeof(low));     int u,v;     for(i=0;i<m;i++)//点从1开始编号     {         scanf("%d%d",&u,&v);         g[u].push_back(v);     }     tarjan(1);     }     return 0;}

0 0
原创粉丝点击