本文仅供本菜鸟复习用。。大家看看就好,笑笑而过。
参考资料:http://wenku.baidu.com/view/ceb92fe2524de518964b7d66.html
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stack>
#include<vector>
#define maxn 5005
#define maxm 100005
#define clr(a,b) memset(a,b,sizeof(a))
using namespace std;
stack<int>s;
vector<int>vc[maxn];
int ca,n,m,bcnt,e,first[maxn],ev[maxm],next[maxm],index;
int dfn[maxn],low[maxn],belong[maxn],x[maxm],y[maxm],mat[maxn];
int instack[maxn],vis[maxn];
void tarjan(int u)
{
int v;
dfn[u]=low[u]=++index; //dfn[u]表示访问u节点的时间戳,即第几个访问,low[u]表示u所在的搜索树的树根的时间戳
s.push(u); //将u压入栈
instack[u]=1; //标记u是否在栈中
for(int i=first[u];i!=-1;i=next[i])
{
v=ev[i];
if(!dfn[v]) //若u的子节点未被访问过则递归v
{
tarjan(v);
low[u]=min(low[u],low[v]); //更新low[u]
}
else if(instack[v]) //若v在栈中则更新low[u]
low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]) //若low[u]==dfn[u],则逐一退栈,直到u==v
{
bcnt++;
do{
v=s.top();
belong[v]=bcnt;
instack[v]=0;
s.pop();
}while(v!=u);
}
}
void init()
{
clr(first,-1);
e=1;
bcnt=0;
index=0;
clr(dfn,0);
clr(low,0);
clr(instack,0);
clr(belong,0);
while(!s.empty()) s.pop();
}