Term Project
Time Limit: 3000ms
Memory Limit: 131072KB
This problem will be judged on UVALive. Original ID: 651164-bit integer IO format: %lld Java class name: Main
解题:强连通分量
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 100010; 4 struct arc{ 5 int to,next; 6 arc(int x = 0,int y = -1){ 7 to = x; 8 next = y; 9 } 10 }e[maxn*10]; 11 int head[maxn],dfn[maxn],low[maxn],belong[maxn],cnt[maxn]; 12 int tot,clk,scc; 13 bool instack[maxn]; 14 stack<int>stk; 15 void init(){ 16 for(int i = tot = clk = scc = 0; i < maxn; ++i){ 17 head[i] = -1; 18 dfn[i] = 0; 19 cnt[i] = belong[i] = 0; 20 instack[i] = false; 21 } 22 while(!stk.empty()) stk.pop(); 23 } 24 void add(int u,int v){ 25 e[tot] = arc(v,head[u]); 26 head[u] = tot++; 27 } 28 void tarjan(int u){ 29 dfn[u] = low[u] = ++clk; 30 instack[u] = true; 31 stk.push(u); 32 for(int i = head[u]; ~i; i = e[i].next){ 33 if(!dfn[e[i].to]){ 34 tarjan(e[i].to); 35 low[u] = min(low[u],low[e[i].to]); 36 }else if(instack[e[i].to]) low[u] = min(low[u],dfn[e[i].to]); 37 } 38 if(low[u] == dfn[u]){ 39 scc++; 40 int v; 41 do{ 42 instack[v = stk.top()] = false; 43 belong[v] = scc; 44 stk.pop(); 45 cnt[scc]++; 46 }while(v != u); 47 } 48 } 49 int main(){ 50 int kase,n; 51 scanf("%d",&kase); 52 while(kase--){ 53 init(); 54 scanf("%d",&n); 55 int ret = 0; 56 for(int i = 1,tmp; i <= n; ++i){ 57 scanf("%d",&tmp); 58 add(i,tmp); 59 ret += i == tmp; 60 } 61 for(int i = 1; i <= n; ++i) 62 if(!dfn[i]) tarjan(i); 63 for(int i = 1; i <= scc; ++i) 64 if(cnt[i] > 1) ret += cnt[i]; 65 printf("%d\n",n - ret); 66 } 67 return 0; 68 }