dfs求联通分量

本文探讨了在战争中城市间高速公路被敌军占领后,如何快速计算出需要修复的高速公路数量,以保持剩余城市的连接。通过深度优先搜索算法,计算在移除某城市节点后的连通分量数,进而确定所需的最小修复路线数。

传送门

1013 Battle Over Cities (25 分)

It is vitally important to have all the cities connected by highways in a war. If a city is occupied by the enemy, all the highways from/toward that city are closed. We must know immediately if we need to repair any other highways to keep the rest of the cities connected. Given the map of cities which have all the remaining highways marked, you are supposed to tell the number of highways need to be repaired, quickly.

For example, if we have 3 cities and 2 highways connecting city​1​​-city​2​​ and city​1​​-city​3​​. Then if city​1​​ is occupied by the enemy, we must have 1 highway repaired, that is the highway city​2​​-city​3​​.

Input Specification:

Each input file contains one test case. Each case starts with a line containing 3 numbers N (<1000), M and K, which are the total number of cities, the number of remaining highways, and the number of cities to be checked, respectively. Then Mlines follow, each describes a highway by 2 integers, which are the numbers of the cities the highway connects. The cities are numbered from 1 to N. Finally there is a line containing K numbers, which represent the cities we concern.

Output Specification:

For each of the K cities, output in a line the number of highways need to be repaired if that city is lost.

Sample Input:

3 2 3
1 2
1 3
1 2 3

Sample Output:

1
0
0

分析:添加的最少的路线,就是他们的连通分量数-1,因为当a个互相分立的连通分量需要变为连通图的时候,只需要添加a-1个路线,就能让他们相连。所以这道题就是求去除了某个结点之后其他的图所拥有的连通分量数
使用邻接矩阵存储,对于每一个被占领的城市,去除这个城市结点,就是把它标记为已经访问过,这样在深度优先遍历的时候,对于所有未访问的结点进行遍历,就能求到所有的连通分量的个数~记得因为有很多个要判断的数据,每一次输入被占领的城市之前要把visit数组置为false

#include<iostream>
#include<string>
#include<stdio.h>
#include<sstream>
#include<math.h>
#include<string.h>
using namespace std;

bool vis[1010];
int a[1010][1010];
int n,m,k;

void dfs(int j)
{
	vis[j]=1;
	for(int i=1;i<=n;i++)
	{
		if(vis[i]==0&&a[i][j]==1) dfs(i);
	}
}

int main()
{
	scanf("%d%d%d",&n,&m,&k);
	memset(a,0,sizeof(a));
	for(int i=0;i<m;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		a[u][v]=1,a[v][u]=1;
	}
	for(int i=0;i<k;i++)
	{
		int t;
		scanf("%d",&t);
		memset(vis,0,sizeof(vis));
		vis[t]=1;
		int cnt=0;
		for(int j=1;j<=n;j++)
		{
			if(vis[j]==0)
			{
				dfs(j);
				cnt++;
			}
		}
		printf("%d\n",cnt-1);
	}
	return 0;
}

 

### 使用DFS算法判断图中的连通分量 对于无向图而言,连通分量指的是该图的一个子集,在这个子集中任何两个顶点间至少存在一条路径连接彼此。为了识别这样的组件,可以采用深度优先搜索(Depth First Search, DFS),这是一种遍历或搜索树或图的数据结构的方式[^1]。 #### 方法概述 通过DFS探索每一个尚未访问的节点,并标记所有能从当前节点到达的其他节点作为同一连通分量的一部分。当整个过程结束时,所有的连通分量就被完全划分出来了。具体来说: - 初始化一个列表`visited[]`用来记录哪些节点已经被处理过; - 对于每个未被访问过的节点执行一次完整的DFS操作; - 每次启动新的DFS意味着发现了一个新的连通分量; - 将属于相同连通分量的所有节点收集起来形成最终的结果集合之一。 #### Python实现示例 下面给出一段简单的Python代码来演示如何使用DFS找出无向图内的全部连通分量: ```python def dfs(graph, start, visited=None): if visited is None: visited = set() stack = [start] while stack: vertex = stack.pop() if vertex not in visited: visited.add(vertex) for neighbor in graph[vertex]: if neighbor not in visited: stack.append(neighbor) return visited def find_connected_components(graph): all_visited = set() # 记录已经访问过的节点 components = [] # 存储各个独立的连通分量 for node in graph.keys(): if node not in all_visited: component = dfs(graph, node) - all_visited components.append(component) all_visited |= component return components ``` 此段程序定义了两个主要功能:一个是标准形式下的DFS(`dfs`),另一个是用来寻找并返回所有连通分量(`find_connected_components`)。前者接收图形对象以及起点参数,后者则迭代调用前者直到覆盖全图为止[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值