求强连通分量
要用到时间戳的概念
算了 直接给模板
ps:借鉴大白皮的写法
1 # include<cstdio> 2 # include<cstring> 3 # include<stack> 4 # include<algorithm> 5 using namespace std; 6 const int N=100000; 7 const int M=500000; 8 int n,m,dfs_clock,ecnt,scc_cnt; 9 int fist[N],next[M],v[M],pre[N],low[N],scc_no[N]; 10 stack<int>S; 11 void built(int a,int b){ 12 v[++ecnt]=b; 13 next[ecnt]=fist[a]; 14 fist[a]=ecnt; 15 } 16 void init(){ 17 int a,b; 18 memset(fist,-1,sizeof(fist)); 19 scanf("%d%d",&n,&m); 20 for(int i=1;i<=m;i++){ 21 scanf("%d%d",&a,&b); 22 built(a,b); 23 } 24 } 25 int dfs(int u){ 26 int lowu=pre[u]=++dfs_clock; 27 int lowv; 28 S.push(u); 29 for(int e=fist[u];e!=-1;e=next[e]) 30 if(!pre[v[e]]) 31 lowu=min(lowu,lowv=dfs(v[e])); 32 else if(!scc_no[v[e]]) 33 lowu=min(lowu,pre[v[e]]); 34 low[u]=lowu; 35 if(pre[u]==low[u]){ 36 scc_cnt++; 37 for(;;){ 38 int x=S.top();S.pop(); 39 scc_no[x]=scc_cnt; 40 if(x==u)break; 41 } 42 } 43 return low[u]; 44 } 45 void find_scc(){ 46 memset(pre,0,sizeof(pre)); 47 memset(scc_no,0,sizeof(scc_no)); 48 for(int i=1;i<=n;i++) 49 if(!pre[i])dfs(i); 50 } 51 void print(){ 52 printf("%d",scc_cnt); 53 } 54 int main(){ 55 init(); 56 find_scc(); 57 print(); 58 return 0; 59 }
时间: 2024-11-03 21:51:15