天梯赛冲刺的第一篇博客,纪念一下啦,希望今年可以拿一个个人奖!!!
题目比较简单,数据范围较小,故不采用链式前向星建图,采用邻接链表方式,方便快捷,
这道题很容易可以看出来用并查集嘛,不排除有小伙伴用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 ;
}