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

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<vector>
 5 #include<stack>
 6 using namespace std;
 7 int n,m,ntime;//ntime记录dfs访问时间
 8 int instack[11000];//标记点是否在栈中
 9 int dfn[11000];//节点在dfs过程中的访问序号(也可以叫做开始时间)
10 int low[11000];//从该节点出发dfs过程中该节点下方节点(开始时间大于该节点的开始时间,且由该节点可达的节点)所能到达的最早的节点的开始时间,初始low数组等于dfn数组
11 vector<vector<int> > g;
12 stack<int> st;
13 void tarjan(int u)
14 {
15     int i,v;
16     dfn[u]=low[u]=ntime++;
17     st.push(u);
18     instack[u]=1;

19     for(i=0;i<g[u].size();i++)//从u出发的每一条边
20     {
21         v=g[u][i];
22         if(dfn[v]==0)//v还没被访问过
23         {
24             tarjan(v);
25             low[u]=min(low[u],low[v]);
26         }
27         else if(instack[v])//v在栈中
28         {
29             low[u]=min(low[u],dfn[v]);
30         }
31     }
32     if(dfn[u]==low[u])//u是一个强连通分量的根
33     {
34         do
35         {
36             v=st.top();
37             st.pop();
38             instack[v]=0;
39             printf("%d ",v);//输出属于这个强连通分量的所有的点的编号
40         }while(u!=v);
41         printf("\n");
42     }
43 }
44 int main()
45 {
46      int i;
47      while(scanf("%d%d",&n,&m)!=EOF)
48      {
49      g.clear();
50      g.resize(11000);
51      while(!st.empty()) st.pop();
52      ntime=1;
53      memset(instack,0,sizeof(instack));
54      memset(dfn,0,sizeof(dfn));
55      memset(low,0,sizeof(low));
56      int u,v;
57      for(i=0;i<m;i++)//点从1开始编号
58      {
59          scanf("%d%d",&u,&v);
60          g[u].push_back(v);
61      }
62      tarjan(1);
63      }
64      return 0;
65 }

 

posted @ 2016-05-05 11:57  2014551532  阅读(162)  评论(0编辑  收藏  举报