【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 }
View Code

 标准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 }
View Code

 

posted on 2019-10-23 13:08  thjkhdf12  阅读(171)  评论(0)    收藏  举报