\quad
这个题目在于求图连通分量个数,我们从任一顶点开始对图进行dfs并记录哪些点被访问,在没有被访问过的点中继续选出任一顶点开始dfs,知道所有点都被访问,进行dfs的次数即为图连通分量个数。题目难点在于在某个点被去除的时候如何进行dfs,很简单,若dfs遍历到需要被去除的那个点我们就直接return掉,表示这条路走不通即可。
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
const int maxn = 1001;
int vis[maxn];
vector<int> E[maxn];
void dfs(int u, int q) // 在不使用节点q的情况下进行dfs
{
if(u==q) return;
vis[u] = 1;
for (int i = 0; i < E[u].size(); ++i)
{
int v = E[u][i];
if(vis[v]==0) dfs(v, q);
}
}
int solve(int N, int q)
{
int cnt = 0;
for (int i = 1; i <= N; ++i)
{
if(vis[i]==0) cnt++, dfs(i, q);
}
return cnt-2; // 去除的顶点算一个连通分量,剩下的n-1个连通分量需要n-2条边连接即可
}
int main(int argc, char const *argv[])
{
ios::sync_with_stdio(false); cin.tie(0), cout.tie(0);
int N, M, K; cin >> N >> M >> K;
while(M--)
{
int a, b; cin >> a >> b;
E[a].push_back(b);
E[b].push_back(a);
}
while(K--)
{
memset(vis, 0, sizeof(vis));
int q; cin >> q;
cout << solve(N, q) << endl;
}
return 0;
}