思路
其实这题实质上就是求去掉某个节点后,图的连通分量个数。这里去掉某个节点可以通过将visited置成1模拟实现,因为dfs不会去访问已访问的节点。我用的是邻接矩阵实现,空间复杂度比较大,可以用邻接表实现,btw并查集也是可以的(可以参考《算法笔记》)
#include <cstdio>
using namespace std;
int N, M, K, G[1010][1010], visited[1010] = {0};
void dfs(int begin){
visited[begin] = 1;
for(int i = 1; i <= N; i++)
if(G[begin][i] == 1 && visited[i] == 0)
dfs(i);
}
int countBlocks(){
int cnt = 0;
for(int i = 1; i <= N; i++){
if(visited[i] == 0){
cnt++;
dfs(i);
}
}
return cnt;
}
int main(){
scanf("%d%d%d", &N, &M, &K);
for(int i = 1; i <= N; i++)
for(int j = 1; j <= N; j++)
G[i][j] = 0;
for(int i = 0; i < M; i++){
int a, b;
scanf("%d%d", &a, &b);
G[a][b] = G[b][a] = 1;
}
for(int i = 0; i < K; i++){
for(int j = 1; j <= N; j++)
visited[j] = 0;
int city;
scanf("%d", &city);
visited[city] = 1;
int blocks = countBlocks();
printf("%d\n", blocks - 1);
}
return 0;
}