题意:给定一张 n 点 m 边的有向图,问有多少个强连通分量点数大于等于2 。
题意看懂基本就没有问题了。
1 #include<stdio.h> 2 #include<string.h> 3 #include<stack> 4 #include<queue> 5 using namespace std; 6 7 const int maxn=1e4+5; 8 const int maxm=5e4+5; 9 10 int head[maxn],point[maxm],nxt[maxm],size; 11 int n,t,scccnt; 12 int stx[maxn],low[maxn],scc[maxn]; 13 int num[maxn]; 14 stack<int>S; 15 16 void init(){ 17 memset(head,-1,sizeof(head)); 18 size=0; 19 memset(num,0,sizeof(num)); 20 } 21 22 void add(int a,int b){ 23 point[size]=b; 24 nxt[size]=head[a]; 25 head[a]=size++; 26 } 27 28 void dfs(int s){ 29 stx[s]=low[s]=++t; 30 S.push(s); 31 for(int i=head[s];~i;i=nxt[i]){ 32 int j=point[i]; 33 if(!stx[j]){ 34 dfs(j); 35 low[s]=min(low[s],low[j]); 36 } 37 else if(!scc[j]){ 38 low[s]=min(low[s],stx[j]); 39 } 40 } 41 if(low[s]==stx[s]){ 42 scccnt++; 43 while(1){ 44 int u=S.top();S.pop(); 45 scc[u]=scccnt; 46 num[scccnt]++; 47 if(s==u)break; 48 } 49 } 50 } 51 52 void setscc(){ 53 memset(stx,0,sizeof(stx)); 54 memset(scc,0,sizeof(scc)); 55 t=scccnt=0; 56 for(int i=1;i<=n;++i)if(!stx[i])dfs(i); 57 } 58 59 int main(){ 60 int m; 61 scanf("%d%d",&n,&m); 62 init(); 63 while(m--){ 64 int a,b; 65 scanf("%d%d",&a,&b); 66 add(a,b); 67 } 68 setscc(); 69 int ans=0; 70 for(int i=1;i<=scccnt;++i)if(num[i]>1)ans++; 71 printf("%d\n",ans); 72 return 0; 73 }
时间: 2024-10-12 17:53:43