题目大意:
给定N座城市,其中有M条边是相连的,如果有其中一个城市被敌人占领的话,求出需要连接多少条边让剩下的城市连通.
算法思路:
该城市的数据结构很显然是一个图的结构,那么我们如果将一个顶点去除后,剩下来的顶点会组成若干个连通分量,那么要让这剩下来的结点全部连接起来变成一个图,那么就等价于将若干个连通分量连接成一个连通分量,我们知道2个连通分量只需要在这2个连通分量分别取出一个顶点然后相连就变成了一个连通分量,所以需要连接的边数就是若干连通分量减一的个数。统计连通分量的个数的方式就是在每次DFS结束后累加就好。使用常规的DFS代码就可以解决了。
注意点:
- 1、不用真正的删除数据节点,不然有可能超时,直接使用一个变量$occupied$保存,在遍历的时候不要访问就好。
- 2、每一次查询都得初始化$visited$数组,不然结果错误。
- 3、无向图得存储两边的数据,也就是得初始化$G[a][b] = G[b][a] = 1;$
提交结果:
AC代码:
#include <cstdio>
#include <cstring>
using namespace std;
int G[1005][1005] = {};//邻接矩阵
int occupied;// 待攻占的城市
bool visited[1005] = {};//访问标记数组
int N,M,K;// 城市数目,路径条数,攻占的城市
void DFS(int start){
visited[start] = true;
for (int i = 1; i <= N; ++i) {
if(G[start][i]!=0&&i!=occupied&&!visited[i]){
// 访问所有与start连通,没有被攻占,并且没有被访问的节点
DFS(i);
}
}
}
void DFSTraverse(){
int connected_component_count = 0;
for (int i = 1; i <= N; ++i) {
if(!visited[i]&&i!=occupied){// i不能是被攻占节点
DFS(i);
++connected_component_count;
}
}
printf("%d\n",connected_component_count-1);
}
int main()
{
scanf("%d %d %d",&N,&M,&K);
int a,b;
for (int i = 0; i < M; ++i) {
scanf("%d %d",&a,&b);
G[a][b] = G[b][a] = 1;
}
for (int j = 0; j < K; ++j) {
scanf("%d",&occupied);
memset(visited,0, sizeof(visited));
DFSTraverse();
}
return 0;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。