PAT甲级1013Battle Over Cities

题目链接

https://pintia.cn/problem-sets/994805342720868352/problems/994805500414115840

题解

题目要求

  • 在战争中,如果一个城市被敌方占领,那通向该城市或者从该城市出发的高速公路都会被关闭,需要修复其它公路保证所有的城市互相连通。(一个图去掉一个顶点,请补充边使该图变为连通图,即所有顶点都被经过)
  • 输入
    • N:小于1000,城市总数,索引为[1,N]
    • M:剩余高速公路的数量
    • K:需要被检查的城市的数量
    • M条高速公路
    • K个需要被检查的城市
  • 输出
    • 对于每个需要检查的城市,如果它被敌方占领,请输出需要修复几条高速公路。

解题思路

知识概念

  • 连通/通路

    如果从顶点x出发,可以到达y,那x和y连通,这条路径就是一个通路

  • 连通图

    如果图G中每两点间皆连通,则G连通图

  • 最大连通子图

    如果在这个子图中在添加一个顶点则该子图不再是连通图,则该子图就是最大连通子图。

  • 连通分量

    无向图G的一个最大连通子图称为G的一个连通分量连通分支

思路

  • 这道题就是求去除某个结点后图中的连通分量数

    添加路线的最小数量,就是去除该顶点后图中的连通分量数-1。

    因为当a个互相分立的连通分量需要变为连通图的时候,只需要添加a-1个路线,就能让他们相连。

  • 一个城市被占领,不用删除和其关联的所有边,只要将该顶点设置为已标记即可,这样DFS时就会忽略该顶点。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// Problem: PAT Advanced 1013
// URL: https://pintia.cn/problem-sets/994805342720868352/problems/994805500414115840
// Tags: DFS 图 连通图 连通分量

#include <iostream>
using namespace std;

const int MAXN = 1001;
int n, m, k;
bool e[MAXN][MAXN];
bool visited[MAXN];

void dfs(int u){
visited[u] = true;
for (int v = 1; v <= n; v++){
if (!visited[v] && e[u][v]){
dfs(v);
}
}
}

int main()
{
scanf("%d %d %d", &n, &m, &k);
int v1, v2;
for (int i = 0; i < m; i++){
scanf("%d %d", &v1, &v2);
e[v1][v2] = e[v2][v1] = true;
}
int occupied;
while (k--){
fill(visited + 1, visited + 1 + n, false);
scanf("%d", &occupied);
visited[occupied] = true;
int num = 0;
for (int i = 1; i <= n; i++){
if (!visited[i]){
dfs(i);
num += 1;
}
}
printf("%d\n", num - 1);
}
return 0;
}

参考链接

https://blog.csdn.net/liuchuo/article/details/52293756


作者:@臭咸鱼

转载请注明出处:https://www.cnblogs.com/chouxianyu/

欢迎讨论和交流!