[PAT解题报告] Battle Over Cities
给定一个无向图,问删掉一个节点(和与之相关联的边)之后,我们需要再新建多少条边,能保证这个图的其他点互相可达。
分析:我们把一个图切成若干个连通分量——每个连通分量当作一个“大”的节点,这些“大”节点之间是没有边相连的,这些“大”节点内部的真正节点是互相连通的。如果有n个“大”节点,我们连(n
- 1)条边,就可以形成一棵树,所有的真正节点之间也都有道路相连了。
所以这个题本质就是删一个节点之后,看连通分量的个数,减1就是答案。求连通分量可以用bfs和dfs,dfs简单点。另外还要注意,如果原始图只有一个节点,删掉这个节点之后就是一个空的图了——所以算连通分量个数要小心答案是0,答案减成-1的情况。
代码:
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
bool a[1024][1024];
int visited[1024];
int n;
void dfs(int now,int x) {
if (visited[now]) {
return;
}
visited[now] = true;
for (int i = 0; i < n; ++i) {
if ((x != i) && a[now][i]) {
dfs(i , x);
}
}
}
int main() {
int m,q;
for (scanf("%d%d%d",&n,&m,&q); m; --m) {
int x,y;
scanf("%d%d",&x,&y);
--x;
--y;
a[x][y] = a[y][x] = true;
}
for (;q;--q) {
int x;
scanf("%d",&x);
--x;
memset(visited,0,sizeof(visited));
int answer = 0;
for (int i = 0; i < n; ++i) {
if ((x != i) && (!visited[i])) {
++answer;
dfs(i, x);
}
}
printf("%d\n",max(--answer, 0));
}
return 0;
}
原题链接 http://www.patest.cn/contests/pat-a-practise/1013

