题目大意:给出图的信息,如果删除指定的顶点,求对于剩余顶点,至少需要加入多少条边才能使图连通。
关键在于想到至少需要新增的边数就是当前连通块的个数 - 1。统计当前连通块的个数用 dfs方法和bfs方法都可以,与常规问题不同的是要删除指定的顶点,也就是遍历到该节点时跳过即可。
AC代码:
DFS:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
using namespace std;
const int MAXN = 1010;
vector<int> G[MAXN];
bool visited[MAXN] = {false};
void dfs(int v, int del)
{
visited[v] = true;
for (int i = 0; i < G[v].size(); ++i)
{
if(!visited[G[v][i]] && G[v][i] != del) dfs(G[v][i], del);
}
}
int main()
{
int N, M, K;
cin >> N >> M >> K;
for (int i = 0; i < M; ++i)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
for (int query = 0; query < K; ++query)
{
fill(visited, visited + MAXN, 0);
int del;
scanf("%d", &del);
int count = 0;
for (int i = 1; i <= N; ++i)
{
if(!visited[i] && i != del)
{
count++;
dfs(i, del);
}
}
printf("%d\n", count-1);
}
return 0;
}
BFS:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <queue>
using namespace std;
const int MAXN = 1010;
vector<int> G[MAXN];
bool visited[MAXN] = {false};
void bfs(int v, int del)
{
queue<int> q;
q.push(v);
visited[v] = true;
while(!q.empty())
{
int now = q.front();
q.pop();
for (int i = 0; i < G[now].size(); ++i)
{
if(!visited[G[now][i]] && G[now][i] != del)
{
q.push(G[now][i]);
visited[G[now][i]] = true;
}
}
}
}
int main()
{
int N, M, K;
cin >> N >> M >> K;
for (int i = 0; i < M; ++i)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
for (int query = 0; query < K; ++query)
{
fill(visited, visited + MAXN, 0);
int del;
scanf("%d", &del);
int count = 0;
for (int i = 1; i <= N; ++i)
{
if(!visited[i] && i != del)
{
count++;
bfs(i, del);
}
}
printf("%d\n", count-1);
}
return 0;
}