并查集与集合合并 [USACO21JAN] Dance Mooves S
我们不妨利用 set 的特性, 对每一头牛创建一个集合, 记录每一头牛经过的点. 我们先模拟一遍, 直到找到了环为止, 即对于每一头牛而言最后回到了自己最初的位置上. 最后合并环.
void dfs(int cow,int rt){
if(cow==rt)return;
visit[cow]=true;
f[rt].insert(f[cow].begin(),f[cow].end());
dfs(::cow[cow],rt);
ans[cow]=f[rt].size();
}
代码:
#include<iostream>
#include<algorithm>
#include<vector>
#include<set>
#define P(A) A=-~A
typedef long long LL;
#define NUMBER1 100000
int n,k,tot(0),cow[NUMBER1+5],ans[NUMBER1+5];
bool visit[NUMBER1+5];
std::set<int>f[NUMBER1+5];
void dfs(int cow,int rt){
if(cow==rt)return;
visit[cow]=true;
f[rt].insert(f[cow].begin(),f[cow].end());
dfs(::cow[cow],rt);
ans[cow]=f[rt].size();
}
signed main(){
std::cin.tie(nullptr)->std::ios::sync_with_stdio(false);
std::cout.tie(nullptr);
std::cin>>n>>k;
for(int i=1;i<=n;P(i))f[i].insert(i),cow[i]=i;
for(int x,y;k--;){
std::cin>>x>>y;
std::swap(cow[x],cow[y]);;
f[cow[x]].insert(y);
f[cow[y]].insert(x);
}
for(int i=1;i<=n;P(i)){
if(!visit[i]){
visit[i]=true;
dfs(cow[i],i);
ans[i]=f[i].size();
}
}
for(int i=1;i<=n;P(i))std::cout<<ans[i]<<'\n';
return 0;
}

浙公网安备 33010602011771号