【codeforces div3 19/10/23】Books Exchange
非标准瞎搜解法
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 5 #define mfor(i,a,b) for(register int i=(a);i<=(b);i++) 6 #define mem(a,b) memset(a,(b),sizeof(a)) 7 8 int T; 9 int n; 10 int tu[1000010]; 11 bool vis[1000010]; 12 int ans[1000010]; 13 14 int dfs(int x, int t, int cnt) 15 { 16 vis[x] = true; 17 if (t == tu[x]) return ans[x] = cnt + 1; 18 return ans[x] = dfs(tu[x], t, cnt + 1); 19 } 20 21 int main() 22 { 23 cin >> T; 24 mfor(p, 1, T) 25 { 26 cin >> n; 27 mem(vis, false); 28 mfor(i, 1, n) cin >> tu[i]; 29 mfor(i, 1, n) 30 { 31 if (!vis[i]) 32 { 33 dfs(i, i, 0); 34 } 35 } 36 mfor(i, 1, n) 37 { 38 cout << ans[i] << " "; 39 } 40 cout << endl; 41 } 42 }
标准tarjan缩点解法
1 #include<iostream> 2 #include<stack> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 7 int T, n; 8 const int maxn = 200010; 9 int dfn[maxn]; //第i个点被dfs到的次序 10 int low[maxn]; //二叉搜索树上i所在子数上仍在栈中的最小dfn,low[i]相等的点在一个强连通分量中 11 bool vis[maxn]; //是否在栈中 12 stack<int>s; 13 int turn[maxn]; 14 int tot; 15 int num[maxn]; //第i个强连通分量的点数 16 int res[maxn]; //res[i]表示i在第几个强连通分量中 17 int cnt; 18 19 void tarjan(int x) 20 { 21 dfn[x] = low[x] = ++cnt; 22 s.push(x); 23 vis[x] = true; 24 if (!dfn[turn[x]]) 25 { 26 tarjan(turn[x]); 27 low[x] = min(low[x], low[turn[x]]); 28 } 29 else if (vis[turn[x]]) 30 { 31 low[x] = min(low[x], dfn[turn[x]]); 32 } 33 if (low[x] == dfn[x]) 34 { 35 tot++; 36 while (!s.empty() && s.top() != x) 37 { 38 int t = s.top(); 39 num[tot]++; 40 res[t] = tot; 41 vis[t] = false; 42 s.pop(); 43 }; 44 s.pop(); 45 num[tot]++; 46 res[x] = tot; 47 vis[x] = false; 48 } 49 } 50 51 int main() 52 { 53 cin >> T; 54 while (T--) 55 { 56 cin >> n; 57 for (int i = 1; i <= n; i++) 58 { 59 cin >> turn[i]; 60 } 61 for (int i = 1; i <= n; i++) 62 { 63 if (!dfn[i]) 64 { 65 tarjan(i); 66 } 67 } 68 for (int i = 1; i <= n; i++) 69 { 70 cout << num[res[i]] << " "; 71 } 72 cout << endl; 73 memset(dfn, 0, sizeof(dfn)); 74 memset(low, 0, sizeof(low)); 75 memset(num, 0, sizeof(num)); 76 memset(res, 0, sizeof(res)); 77 tot = 0; 78 cnt = 0; 79 } 80 }
浙公网安备 33010602011771号