求出不带特定点有几个连通分量,答案就是连通分量-1
首先解释一下连通分量
无向图G的极大连通子图称为G的连通分量( Connected Component)。任何连通图的连通分量只有一个,即是其自身,非连通的无向图有多个连通分量。
简单来说就是如果一个图任何一点都可以到达,那么这个图就是连通图,连通图只有一个连通分量,而对于不是连通图的图来说,有几部分就是几个连通分量
这道题首先给我们一个图,然后让我们求把图中的某个点去掉之后,剩下的点至少还需要恢复几条路才可以成为连通图,我们把去掉那个点之后,每一个连通的那一部分当成一个点,也就是一个连通分量,问题就变成了剩下的n个点,恢复几条边能使他们连通,只需要n-1条边即可
求连通分量只需要用一个dfs即可,用一个布尔数组v代表我们是否访问过这个点,用二维数组w表示x和y之间是否有路,如何去掉特定点呢,其实就是直接把它的v设为true,这样我们寻找有几个连通分量就跟这个点无关,求出有n个连通分量,答案就是n-1,因为n个部分,只需要n-1条边就可以将这n部分连接起来
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,k;
bool w[1010][1010];
bool v[1010];
void dfs(int x) {
v[x]=true;
for(int i=1;i<=n;i++) {
if(!v[i]&&w[x][i]) {
dfs(i);
}
}
}
int main() {
scanf("%d%d%d",&n,&m,&k);
int x,y;
for(int i=1;i<=m;i++) {
scanf("%d%d",&x,&y);
w[x][y]=w[y][x]=true;
}
while(k--) {
int ans=0;
scanf("%d",&x);
memset(v,0,sizeof(v));
v[x]=true;
for(int i=1;i<=n;i++) {
if(!v[i]) {
dfs(i);
ans++;
}
}
printf("%d\n",ans-1);
}
return 0;
}