并查集

本次题目:简单题但卡壳了

题目简叙:将这个无向图建立起来,对其进行操作:删除最小边数,使其不再有环,求最小操作次数

想法:使用并查集,把相连的集合合并,然后再进行遍历,判断有几个find(i)==i,就是对应的环数,就这样吗?
不对,假如这个集合有多个环呢?所以,我们一开始就要算对于集合中多余的环数,怎么算?
假如一个集合只有一个环,那他的点数应该等于边数
所以我们先要除去多余的边数,然后再进行find(i)==i判断累加即可

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=200010;
int f[N];
int n, m, ans, cnt;
int find(int x)
{
if(f[x]!=x) f[x]=find(f[x]);
return f[x];

}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)
f[i]=i;
for(int i=1;i<=m;i++)
{
int p, q;
cin>>p>>q;
f[find(p)]=find(q);
}
int cnt=m-n;
for(int i=1;i<=n;i++)
{
if(find(i)==i)
cnt++;
}
cout<<cnt<<endl;
return 0;
}