一个DFS的题,一开始当做并查集的题来做了。。
思路就是对每个没有被访问过的节点进行图的遍历,如果只有一个连通分支,则只需要DFS一次就可以;若有多个连通分支,就会进行多次DFS。
在空间允许的情况下最好使用一个临时二维数组来存储每次去掉一个节点后的图,遍历完恢复就可以了。
#include <iostream>
#include<stdio.h>
using namespace std;
int N,M,K;
int de;
int num;
bool G[2000][2000];
bool tG[2000][2000];
bool vis[2000];
void detach(int x)
{
for(int i = 1;i<=N;i++)
{
tG[i][x] = false;
tG[x][i] = false;
}
}
void DFS(int x)
{
vis[x] = true;
for(int i = 1;i<=N;i++)
{
if(i != de && tG[x][i] && !vis[i])
{
DFS(i);
}
}
}
void DFSTrave()
{
for(int i = 1;i<=N;i++)
{
if(i != de && !vis[i])
{
DFS(i);
num++;
}
}
}
int main()
{
scanf("%d %d %d",&N,&M,&K);
int temp1,temp2;
for(int i = 0;i<M;i++)
{
scanf("%d %d",&temp1,&temp2);
G[temp1][temp2] = true;
G[temp2][temp1] = true;
tG[temp1][temp2] = true;
tG[temp2][temp1] = true;
}
int temp;
for(int i = 0;i < K;i++)
{
scanf("%d",&temp);
num = -1;
detach(temp);
de = temp;
DFSTrave();
for(int j = 1;j<=N;j++)
{
vis[j] = false;
for(int k = 1;k<=N;k++)
{
tG[j][k] = tG[k][j] = G[j][k]; //recover
}
}
printf("%d\n",num);
}
return 0;
}