Mouse Hunt

思路:利用并查集将会出现在同一个房间的下标统一化

在深度遍历中寻找同一房间的下标们消耗最小值

若是在老鼠跳转中出现a[i]=i,则连同同一房间的老鼠们都会去i房间

若是出现回环,则比较回环中的最小值

 1 typedef long long ll;
 2 typedef pair<int, int> p;
 3 typedef unsigned long long ull;
 4 int n;
 5 int c[200005];
 6 int a[200005];
 7 int v[200005];
 8 int visited[200005];
 9 int fa[200005], rankv[200005];
10 int fin(int v) {
11     return fa[v] = fa[v] == v ? v : fin(fa[v]);
12 }
13 
14 ll ans = 0;
15 int dfs(int ind, int minc = 200000) { //遍历找到最后的顶点
16     v[ind]++;
17     // a[i]=i时或者出现a数组出现环时循环找出最小值
18     if (v[ind] >= 3) {
19     //    cout << v[ind] << endl;
20         ans += minc;
21         return 1;
22     }
23     if (v[ind] == 2) {
24    //     cout << v[ind] << endl;
25         dfs(a[ind], min(minc, c[ind]));
26     }
27     else {
28    //     cout << v[ind] << endl;
29         dfs(a[ind], minc);
30     }
31     return 0;
32 }
33 
34 int main() {
35     cin >> n;
36     for (int i = 1; i <= n; i++) {
37         fa[i] = i;
38         rankv[i] = 0;
39     }
40     for (int i = 1; i <= n; i++) {
41         cin >> c[i];
42     }
43     for (int i = 1; i <= n; i++) {
44         cin >> a[i];
45         int x = fin(i), y = fin(a[i]);
46         if (rankv[x] < rankv[y]) {
47             fa[x] = y;
48         }
49         else {
50             fa[y] = x;
51             if (rankv[y] == rankv[x]) {
52                 ++rankv[x];
53             
54             }
55         }
56     }
57     for (int i = 1; i <= n; i++) {
58         if (visited[fin(i)] == 0) {
59             visited[fin(i)] = 1;
60             dfs(fin(i));
61         }
62     }
63     printf("%lld\n", ans);
64     return 0;
65 }

 

posted @ 2020-08-02 22:57  吉吉的奥利奥  阅读(12)  评论(0编辑  收藏