此题可以转化为求删除一个结点后的连通子图的数量,删除结点可以通过DFS直接return的方法来实现。
#include <cstdio>
#include <vector>
using namespace std;
vector<int> city[1010];
bool visited[1010];
int n, m, k;
void DFS(int index, int del){
if(index == del) return;
visited[index] = true;
for(int i=0; i<city[index].size(); i++){
int temp = city[index][i];
if(!visited[temp]){
DFS(city[index][i], del);
}
}
}
void init(){
for(int i=0; i<1010; i++){
visited[i]= false;
}
}
int main(){
scanf("%d %d %d", &n, &m, &k);
for(int i=0; i<m; i++){
int c1, c2;
scanf("%d %d", &c1, &c2);
city[c1].push_back(c2);
city[c2].push_back(c1);
}
for(int i=0; i<k; i++){
init();
int del;
scanf("%d", &del);
int num = 0;
for(int j=1; j<=n; j++){
if(!visited[j]){
DFS(j, del);
num++;
}
}
printf("%d\n", num-2);
}
return 0;
}
————————————————————————————————————————
并查集做法
#include <cstdio>
#include <vector>
using namespace std;
vector<int> adj[1010];
int father[1010];
bool visited[1010];
int n, m, k;
void init(){
for(int i=0; i<1010; i++){
father[i] = i;
visited[i] = false;
}
}
int findfather(int x){
int a = x;
while(x != father[x]){
x = father[x];
}
while(a != father[a]){
int z = a;
a = father[a];
father[z] = x;
}
return x;
}
void Union(int a, int b){
int fa = findfather(a);
int fb = findfather(b);
if(fa != fb){
father[fa] = fb;
}
}
int main(){
scanf("%d %d %d", &n, &m, &k);
for(int i=0; i<m; i++){
int t1, t2;
scanf("%d %d", &t1, &t2);
adj[t1].push_back(t2);
adj[t2].push_back(t1);
}
for(int i=0; i<k; i++){
init();
int del;
scanf("%d", &del);
for(int j=1; j<=n; j++){
for(int p=0; p<adj[j].size(); p++){
if(j!=del && adj[j][p]!=del){
Union(j,adj[j][p]);
}
}
}
int num = 0;
for(int j=1; j<=n; j++){
if(j == del) continue;
if(!visited[findfather(j)]){
num++;
visited[findfather(j)] = true;
}
}
printf("%d\n", num-1);
}
return 0;
}