“Tarjan有三种算法 你们知道吗”——Tar乙己
void tarjan(int x) { low[x]=dfn[x]=++ind; q[++top]=x;mark[x]=1; for(int i=last[x];i;i=e[i].next) if(!dfn[e[i].to]) { tarjan(e[i].to); low[x]=min(low[x],low[e[i].to]); } else if(mark[e[i].to]) low[x]=min(low[x],dfn[e[i].to]); if(low[x]==dfn[x]) { int now=0;scc++; while(now!=x) { now=q[top--];mark[now]=0; bl[now]=scc;num[scc]++; } } }
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<vector> using namespace std; const int maxn=50010; int first[maxn],to[maxn],next[maxn],cnt,from[maxn]; void add(int u,int v) { from[++cnt]=u; to[cnt]=v; next[cnt]=first[u]; first[u]=cnt; } int dfn[maxn],low[maxn],vis[maxn],ind,scc,now,st[maxn],top; int isc[maxn]; vector<int> bl[maxn]; int blc; int tag[maxn]; void Tarjan_dfs(int x,int fa) { int son=0; low[x]=dfn[x]=++ind; for(int i=first[x];i;i=next[i]) { int now=to[i]; if(!dfn[now]) { st[++top]=i;son++; Tarjan_dfs(now,x); low[x]=min(low[x],low[now]); if(low[now]>=dfn[x]) { isc[x]=1; bl[++blc].clear(); while(1) { int num=st[top--]; if(tag[from[num]]!=blc) { bl[blc].push_back(from[num]); tag[from[num]]=blc; } if(tag[to[num]]!=blc) { bl[blc].push_back(to[num]); tag[to[num]]=blc; } if(to[num]==now && from[num]==x)break; } } } else if(dfn[now]<dfn[x] && now!=fa) { st[++top]=i; low[x]=min(low[x],dfn[now]); } } if(fa==0 && son==1)isc[x]=0; } int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v); add(v,u); } for(int i=1;i<=n;i++)if(!dfn[i])Tarjan_dfs(i,-1); cout<<blc<<endl; return 0; }
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<vector> using namespace std; const int maxn=50010; int first[maxn],to[maxn],next[maxn],cnt,from[maxn]; void add(int u,int v) { from[++cnt]=u; to[cnt]=v; next[cnt]=first[u]; first[u]=cnt; } int dfn[maxn],low[maxn],vis[maxn],ind,scc,now,st[maxn],top; int isb[maxn]; vector<int> bl[maxn]; int blc; int tag[maxn]; void Tarjan_dfs(int x,int fa) { dfn[x]=low[x]=++ind; for(int i=first[x];i;i=next[i]) { int v=to[i]; if(!dfn[v]) { Tarjan_dfs(v,x); low[x]=min(low[x],low[v]); if(low[v]>dfn[x]) isb[i]=isb[i^1]=1; } else if(dfn[v]<dfn[x] && v!=fa)low[x]=min(low[x],dfn[v]); } } int vis[maxn]; void dfs(int x) { vis[x]=1; tag[x]=blc; for(int i=first[x];i;i=next[i]) { int v=to[i]; if(isb[v])continue; if(!vis[i])dfs(v); } } int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int u,v; scanf("%d%d",&u,&v); add(u,v); add(v,u); } for(int i=1;i<=n;i++)if(!dfn[i])Tarjan_dfs(i,-1); for(int i=1;i<=n;i++)if(!vis[i]){blc++;dfs(i);} cout<<blc<<endl; return 0; }