PAT A1013 Battle Over Cities
思路:本题可以用DFS和并查集两种做法。
DFS:对图进行DFS遍历,得到若干个连通分量,需要补充的道路数量即为连通分量-1
并查集:对被删除之外的点进行Union,最后查询集合个数,等同于连通分量数
//DFS
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
const int maxn = 1005;
vector<int> G[maxn];
bool visit[maxn];
int N, M, K;
int delVertex;
void DFS(int v) {
if(v == delVertex) return;
visit[v] = true;
for(int i = 0; i < G[v].size(); i++)
if(!visit[G[v][i]]) DFS(G[v][i]);
}
int main() {
scanf("%d %d %d", &N, &M, &K);
int v1, v2;
for(int i = 0; i < M; i++) {
scanf("%d %d", &v1, &v2);
G[v1].push_back(v2);
G[v2].push_back(v1);
}
int block;
for(int q = 0; q < K; q++) {
scanf("%d", &delVertex);
memset(visit, false, sizeof(visit));
block = 0;
for(int i = 1; i <= N; i++) {
if(i != delVertex && !visit[i]) {
DFS(i);
block++;
}
}
printf("%d\n", block - 1);
}
return 0;
}
//并查集
#include<cstdio>
#include<vector>
using namespace std;
const int maxn = 1005;
vector<int> G[maxn];
bool visit[maxn];
int father[maxn];
int N, M, K;
int delVertex;
int findFather(int x) {
int temp = x;
while(x != father[x])
x = father[x];
int a;
while(temp != father[temp]) {
a = temp;
temp = father[temp];
father[a] = 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);
int v1, v2;
for(int i = 0; i < M; i++) {
scanf("%d %d", &v1, &v2);
G[v1].push_back(v2);
G[v2].push_back(v1);
}
int block;
for(int q = 0; q < K; q++) {
scanf("%d", &delVertex);
for(int i = 1; i <= N; i++) {
father[i] = i;
visit[i] = false;
}
for(int i = 1; i <= N; i++) {
for(int j = 0; j < G[i].size(); j++) {
v1 = i, v2 = G[i][j];
if(v1 == delVertex || v2 == delVertex)
continue;
Union(v1, v2);
}
}
block = 0;
for(int i = 1; i <= N; i++) {
if(i == delVertex) continue;
int f = findFather(i);
if(!visit[f]) {
block++;
visit[f] = true;
}
}
printf("%d\n", block - 1);
}
return 0;
}