CSES 1751 Planets Cycles 題解

本文最後更新於:2022年12月5日 下午

CSES 1751

題序

見原題

解法

對於每個點有兩種狀態:

  1. 在環裡:答案就是環的大小
  2. 不在環裡:距離最近的環的大小 + 距離

所以一開始可以先將所有環求出來,對於環內的所有點可以直接求出答案。

至於不在環裡的,可以用遞迴暴力搜到答案,可以證明這樣的時間複雜度會在 $\mathcal{O}(n)$

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <bits/stdc++.h>
#define Weakoying ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
#define int long long
#define pii pair<int, int>
#define vi vector<int>
#define vii vector<pair<int, int>>
#define pqueue priority_queue
#define pb push_back
#define F first
#define S second
#define max(a, b) (a > b ? a : b)
#define min(a, b) (a < b ? a : b)
#define cmax(a, b) a = (a > b ? a : b)
#define cmin(a, b) a = (a < b ? a : b)
#define put(x) cout << x << endl;
#define DB(x) cerr << #x << " " << x << endl
#define all(v) v.begin(), v.end()
#define stop system("pause");
#define MEM(x, n) memset(x, n, sizeof(x));
#define lowbit(x) x &(-x)
#define SZ(v) ((int)v.size())
#if !LOCAL
#define endl "\n"
#pragma GCC optimize("Ofast", "unroll-all-loops")
#endif
const int INF = 0x3f3f3f3f3f3f3f3f;
const int P = 1e9+7;

using namespace std;
/******************************************************************************/
#define MAXN 200005
#define MAXM 1000005
int n, m;
int nxt[MAXN];
int vis[MAXN];
int ans[MAXN];
vector<vector<int>> cycle;
vector<int> path;

void dfs(int i) {
path.pb(i);
vis[i] = 2;

int e = nxt[i];
if (vis[e] == 2) {
vector<int> tmp;
for (int j = SZ(path) - 1; j >= 0; j--) {
tmp.pb(path[j]);
if (path[j] == e)
break;
}
cycle.push_back(tmp);
}
else if (!vis[e])
dfs(e);

vis[i] = 1;
path.pop_back();
}

int cal(int i) {
if (ans[i])
return ans[i];
return ans[i] = cal(nxt[i]) + 1;
}

void sol() {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> nxt[i];

for (int i = 1; i <= n; i++) if (!vis[i]) {
dfs(i);
}

for (auto &cyc: cycle) {
for (auto it: cyc) {
ans[it] = cyc.size();
}
}

MEM(vis, 0);

for (int i = 1; i <= n; i++) if (!ans[i]) {
ans[i] = cal(i);
}

for (int i = 1; i <= n; i++)
cout << ans[i] << " \n"[i == n];
}

signed main() {
Weakoying;
int t = 1;
//while (cin >> t)
{
while (t--) {
sol();
}
}

return 0;
}

CSES 1751 Planets Cycles 題解
http://koyingtw.github.io/CSES-1751/
作者
Koying
發布於
2022年12月5日
許可協議