蓝桥杯2013年第四届真题-危险系数(并查集)

        从这个题目中,我们清楚这是寻找边与边的关系,但是这并不是树,因此我们无法通过构建树来完成题目,对于联通块问题,如果bfs不方便为图标记,那么我们可以通过并查集来寻找联通块,先寻找起始节点与目标结点是否连通(在同一组内),如果不在一组内先输出-1,如果在一组内,就在此基础上再进行逐个删除其他结点的并查集,如果删除某个节点后不能再连通,就ans++

        上代码

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 1010;
int x[N], y[N];//存储数据 
int n, m;
int p[N]; 
int st, en; 

int find(int x)//查找父节点
{
	if(x != p[x]) return find(p[x]);//如果x父节点不等于他本身,那就递归继续寻找父节点
	return p[x]; 
}
 
bool check(int u)
{
	for(int i = 1; i <= n; i++){
		p[i] = i;
	}
	
	for(int i = 1; i <= m; i++){
		if(x[i] == u || y[i] == u) continue;//如果遇到u结点就直接跳过 
		
		int px = find(x[i]), py = find(y[i]);
		if(px != py) p[px] = py;
	}
	
	return find(st) != find(en);
}
 

int main(void)
{
	cin >> n >> m;
	
	for(int i = 0; i <= n; i++) p[i] = i;
	
	for(int i = 1; i <= m; i++){
		cin >> x[i] >> y[i]; 
		int px = find(x[i]), py = find(y[i]);//寻找x[i]与y[i]的父节点
		if(px != py) p[px] = py;//如果x[i]与y[i]的父节点不同,就让x的父节点等于y的父节点 
	}
	cin >> st >> en;//输入起始节点和目标节点 
	if(find(st) != find(en)){ 
		cout << -1 << endl;
		return 0;
	}//如果起始节点和目标节点的父节点不同,说明他们不联通,因此输出-1 
	
	int ans = 0;
	for(int i = 1; i <= n; i++){//枚举所有点,并检查这个点是不是关键点 
		if(i != st && i != en){
			if(check(i)) ans++;//如果删除该点无法连通,那就是关键点 
		}
	}
	cout << ans << endl;
	
	return 0;
} 

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值