P8907 题解
Part 1:前言
谢谢这道题让我意识到我在启发式合并方面一窍不通。
感觉这是 Pt 组最简单的一题
Part 2:正文
考虑一个性质,每次互相连边显然有些多余,不妨转化成将编号最小的点和其它点连边。
考虑正确性,若一头牛
直接连边复杂度是
Part 3:代码
const int N=2e5+7;
int n,m;
set<int>g[N];
void Main(){
n=read();m=read();
for(int i=1;i<=m;i++){
int u=read(),v=read();
g[min(u,v)].insert(max(u,v));
}
ll ans=-m;
for(int i=1;i<=n;i++){
if(g[i].empty())continue;
ans+=g[i].size();
int u=*g[i].begin(),v=i;g[v].erase(g[v].begin());
if(g[u].size()<g[v].size())swap(g[u],g[v]);
for(auto i:g[v])g[u].insert(i);
}
cout<<ans;
return;
}