花了很长时间去理解Tarjan
因为看ppt时 自动略过了有文字的一页
导致后面的怎么也想不明白
以下参考曹文老师课件:
一个讲tarjan讲的很详细的博客:http://blog.csdn.net/jeryjeryjery/article/details/52829142?locationNum=4&fps=1
重点理解:
代码实现的时候花了很长时间
小心细节
静态调试很重要
有时候是自己生成的数据错了
具体实现:
#include<bits/stdc++.h>
#define maxn 100005
#define maxm 300005
using namespace std;
template <typename T> void read(T &x){
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar())x=(x<<1)+(x<<3)+ch-'0';
x*=f;
}
int n,m;
int cnt;
int head[maxn],tot;
bool vis[maxn];
int to[maxm],nxt[maxm];
int st[maxn],top,dfs_num;
int dfn[maxn],low[maxn];
void add(int u,int v){
++tot;
to[tot]=v;
nxt[tot]=head[u];
head[u]=tot;
}
void Tarjan(int x){
dfn[x]=low[x]=++dfs_num;
vis[x]=1;
st[++top]=x;
for(int e=head[x];e;e=nxt[e]){
if(!dfn[to[e]]){
Tarjan(to[e]);
low[x]=min(low[x],low[to[e]]);
}
else if(vis[to[e]]) low[x]=min(low[x],dfn[to[e]]);
}
if(dfn[x]==low[x]){
//cout<<x<<endl;
++cnt;
int j;
do{
j=st[top--];
cout<<j<<" ";
vis[j]=0;
}while(j!=x);
cout<<endl;
}
}
int main(){
read(n),read(m);
for(int i=1;i<=m;++i){
int u,v;
read(u),read(v);
add(u,v);
}
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(vis,0,sizeof(vis));
memset(st,0,sizeof(st));
for(int i=1;i<=n;++i) if(!dfn[i]) Tarjan(i);
//for(int i=1;i<=n;++i) cout<<dfn[i]<<" "<<low[n]<<endl;
cout<<cnt<<endl;
return 0;
}