Codeforces--Books Exchange (hard version)

本文详细解析了Codeforces竞赛中B2题目的解决方案,采用并查集算法思想,通过构造集合并计算每个集合的大小来解决题目。文章提供了完整的代码实现,并解释了时间复杂度分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接http://codeforces.com/contest/1249/problem/B2 。并查集思想,将数分成多个集合,每个集合的大小就是一轮的所需天数。

Map[i]存储数据。

flag[i]来表示第i个数是否被访问过。

mm[i]记录第i个集合所对应的集合大小,索引i为第i个集合的根对应的值。

getParent方法利用递归的思想更新每个节点的上继,直接指向当前集合的根。

由于访问过的集合不再进行访问,因此,分析时间复杂度,准确是O(CN),C为一个常数。在这里需要注意的是,mm在每次使用后要清,不然会有问题。

 1 #include<bits/stdc++.h>
 2 
 3 /*
 4 * 并查集
 5 */
 6 
 7 using namespace std;
 8 
 9 static const int MAX = 200005;
10 
11 int Map[MAX];
12 bool flag[MAX];
13 map<int, int> mm;
14 
15 int getParent(int x){
16     if(!flag[x]){
17         flag[x] = true;
18         Map[x] = getParent(Map[x]);
19     }
20     return Map[x];
21 }
22 
23 int main(){
24     int q;
25     scanf("%d", &q);
26     while(q--){
27         int n;
28         scanf("%d", &n);
29         for(int i=1;i<=n;i++){
30             flag[i] = false;
31         }
32 
33         // construct set
34         int tmp;
35         for(int i=1;i<=n;i++){
36             scanf("%d", &Map[i]);
37         }
38 
39         // solve
40         for(int i=1;i<=n;i++){
41             int parent = getParent(i);
42             mm[parent]++;
43         }   
44 
45         for(int i=1;i<=n;i++){
46             if(i==1){
47                 printf("%d", mm[Map[i]]);
48             }
49             else{
50                 printf(" %d", mm[Map[i]]);
51             }
52         }
53         printf("\n");
54         mm.clear();
55     }
56     return 0;
57 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值