tarjan 较裸的一道题, 难在建图。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int N = 1000010; 6 int a[N] , dfn[N] , low[N]; 7 int tot , top; 8 int sta[N]; 9 bool ins[N]; 10 int bel[N] , cnt , cd[N]; 11 void tarjan(int x) 12 { 13 dfn[x] = low[x] = ++tot; 14 ins[x] = 1; 15 sta[++top] = x; 16 if(!dfn[a[x]]) 17 tarjan(a[x]) , low[x] = min(low[x] , low[a[x]]); 18 else 19 if(ins[a[x]]) 20 low[x] = min(low[x] , dfn[a[x]]); 21 if(dfn[x] == low[x]) 22 { 23 int t; 24 cnt ++ ; 25 do 26 { 27 t = sta[top -- ]; 28 ins[t] = 0; 29 bel[t] = cnt; 30 }while(t != x); 31 } 32 } 33 int main() 34 { 35 int n , i , ans = 0; 36 scanf("%d" , &n); 37 for(i = 1 ; i <= n ; i ++ ) 38 scanf("%d" , &a[i]); 39 for(i = 1 ; i <= n ; i ++ ) 40 if(!dfn[i]) 41 tarjan(i); 42 for(i = 1 ; i <= n ; i ++ ) 43 if(bel[i] != bel[a[i]]) 44 cd[bel[i]] ++ ; 45 for(i = 1 ; i <= cnt ; i ++ ) 46 if(!cd[i]) 47 ans ++ ; 48 printf("%d " , ans); 49 return 0; 50 }