题目信息
题目链接
Luogu CF1833E、Codeforces 1833E
题面翻译
有 \(n\) 个人围成若干个圈(也有可能只有一个)跳舞,每个圈至少有 \(2\) 个人。在圈中,每个人都与 \(2\) 个人相邻。特殊地,如果圈里只有 \(2\) 个人,则实际上只与一个人相邻。
现在,每个人都只记得与自己相邻的人之一,你需要给出这些人围成的圈数的最小值和最大值。
题目描述
$ n $ people came to the festival and decided to dance a few round dances. There are at least $ 2 $ people in the round dance and each person has exactly two neighbors. If there are $ 2 $ people in the round dance then they have the same neighbor on each side.
You decided to find out exactly how many dances there were. But each participant of the holiday remembered exactly one neighbor. Your task is to determine what the minimum and maximum number of round dances could be.
For example, if there were $ 6 $ people at the holiday, and the numbers of the neighbors they remembered are equal $ [2, 1, 4, 3, 6, 5] $ , then the minimum number of round dances is $ 1 $ :
- $ 1 - 2 - 3 - 4 - 5 - 6 - 1 $
and the maximum is $ 3 $ : - $ 1 - 2 - 1 $
- $ 3 - 4 - 3 $
- $ 5 - 6 - 5 $
输入格式
The first line contains a positive number $ t $ ( $ 1 \le t \le 10^4 $ ) — the number of test cases. The following is a description of the test cases.
The first line of the description of each test case contains a positive number $ n $ ( $ 2 \le n \le 2 \cdot 10^5 $ ) — the number of people at the holiday.
The second line of the description of each test case contains $ n $ integers $ a_i $ ( $ 1 \le a_i \le n, a_i \neq i $ ) — the number of the neighbor that the $ i $ th person remembered.
It is guaranteed that the test cases are correct and corresponds to at least one division of people into round dances.
It is guaranteed that the sum of $ n $ for all test cases does not exceed $ 2 \cdot 10^5 $ .
输出格式
For each test case, output two integers — the minimum and maximum number of round dances that could be.
样例 #1
样例输入 #1
10
6
2 1 4 3 6 5
6
2 3 1 5 6 4
9
2 3 2 5 6 5 8 9 8
2
2 1
4
4 3 2 1
5
2 3 4 5 1
6
5 3 4 1 1 2
5
3 5 4 1 2
6
6 3 2 5 4 3
6
5 1 4 3 4 2
样例输出 #1
1 3
2 2
1 3
1 1
1 2
1 1
1 1
2 2
1 2
1 1
思路分析
一道很好的带权并查集。
记录:\(circle_i\) 表示 \(i\) 的并查集中是否已经出现了环,\(sz_i\) 表示 \(i\) 的并查集的大小。
最多的肯定是连通块的数量,最少的只需要让不是环的相连即可。
代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5+10;
//DSU
int T,n,near[MAXN];
bool circle[MAXN];
int fath[MAXN],sz[MAXN];
int get_father(int x){
if(fath[x]==x) return x;
return fath[x] = get_father(fath[x]);
}
void clear(){
for(int i = 1;i<=n;i++){
fath[i] = i;
circle[i] = 0;
sz[i] = 1;
}
}
signed main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
clear();
for(int i = 1;i<=n;i++){
scanf("%d",near+i);
}
for(int i = 1;i<=n;i++){
int fn = get_father(near[i]);
int f = get_father(i);
if(f!=fn){
fath[fn] = f;
circle[f] = circle[f]|circle[fn];
sz[f] += sz[fn];
}else{
if(near[near[i]]!=i) circle[fn] = 1;
}
}
int sum_circle = 0,sum = 0;
for(int i = 1;i<=n;i++){
if(get_father(i)==i){
sum++;
if(circle[i]&&sz[i]!=2){
sum_circle++;
}
}
}
printf("%d %d\n",min(sum,sum_circle+1),sum);
}
return 0;
}
标签:le,people,Dance,number,round,each,test,Round
From: https://www.cnblogs.com/gutongxing/p/18236192