题目链接
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时就会忽略该顶点。
代码
// 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
", num - 1);
}
return 0;
}
参考链接
https://blog.csdn.net/liuchuo/article/details/52293756
作者:@臭咸鱼
转载请注明出处:https://www.cnblogs.com/chouxianyu/
欢迎讨论和交流!