CF1833E Round Dance
我们用并查集求最大值,然后看有多少个没有闭环的并查集(有邻居数<=2的就是未闭环),设未闭环的总共有num个。若num>0,那么答案就是cnt-num+1个。注意每一次要状态恢复
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int T;
int n;
int a[N];
int p[N];
int find(int x)
{
if(p[x]==x)
{
return x;
}
return p[x]=find(p[x]);
}
void merge(int x,int y)
{
int rx=find(x),ry=find(y);
if(rx!=ry)
{
p[rx]=ry;
}
}
set<int> g[N];
map<int,int> mp;
struct node
{
set<int> t;
}q[N];
int minx;
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>n;
for(int i=1;i<=n;i++)
{
p[i]=i;
g[i].clear();
q[i].t.clear();
}
for(int i=1;i<=n;i++)
{
cin>>a[i];
merge(i,a[i]);
g[i].insert(a[i]);
g[a[i]].insert(i);
}
int cnt=0;
mp.clear();
for(int i=1;i<=n;i++)
{
if(p[i]==i)
{
cnt++;
mp[p[i]]=cnt;
}
}
for(int i=1;i<=n;i++)
{
int rt=find(i);
q[mp[rt]].t.insert(i);
}
int num=0;
for(int i=1;i<=cnt;i++)
{
bool flag=false;
for(const auto& elem : q[i].t)
{
if(g[elem].size()<2)
{
flag=true;
break;
}
}
if(flag)
{
num++;
}
}
minx=0;
if(num>=2)
{
minx=cnt-(num-1);
}
else
{
minx=cnt;
}
cout<<minx<<' '<<cnt<<endl;
}
return 0;
}

浙公网安备 33010602011771号