天梯赛冲刺的第一篇博客,纪念一下啦,希望今年可以拿一个个人奖!!!
题目比较简单,数据范围较小,故不采用链式前向星建图,采用邻接链表方式,方便快捷,
这道题很容易可以看出来用并查集嘛,不排除有小伙伴用dfs/bfs,但我更建议用并查集,在数据范围较大的时候,并查集(不要用裸的ok?路径压缩一下嘛)依旧强大,yyds!!!
主旨思路:遍历每个点,然后每个点连着的点都findf一下,看一下是不是同一个baba,不是的话就合并一下,注意如果是被砍掉的点要continue。最后一步,每个点findf一下,看看有几个连通块,连通块-1就是要建的边数,由于被砍掉的独立点,也是一个连通块,用样例自己画一下就出来了,但我们并不用和他建立边,所以要-2!
over,今天2022/3/12航大考试还可以欸,98(rank7/40+),对不起,我提前交卷来写这篇blog了,最小堆我真的没看懂,唉,fyx有点猛欸,范老师也要加油哇!
代码附上,回家看比赛 嘿嘿嘿
#include <cstdio> #include <iostream> #include <string> #include <cmath> #include <vector> #include <algorithm> using namespace std; vector<int>V[1005]; int fa[1005]; int n,m,k; void init() { for(int i = 1;i <= n;i++) { fa[i]=i; } } int findf(int x) { if(x==fa[x]) return x; return fa[x]=findf(fa[x]); } int main() { cin >> n >> m >> k; for(int i = 1;i <= m;i++) { int a,b; cin >> a >> b; V[a].push_back(b); V[b].push_back(a); } for(int i = 1;i <= k;i++) { init(); int tt; cin >> tt; for(int j = 1;j <= n;j++) { if(j==tt) continue; for(int z = 0;z < V[j].size();z++) { if(V[j][z]==tt) continue; int a=findf(j); int b=findf(V[j][z]); if(a!=b) fa[a]=b; } } int ans=0; for(int ii = 1;ii <= n;ii++) { if(findf(ii)==ii) ans++; } if(i!=k) cout << ans-2 <<endl; else cout << ans-2; } return 0 ; }