分而治之——图的连通性问题及板子

news2024/9/20 22:42:06

连通性的判断 

两大算法:并查集 和 图的遍历(DFS BFS) 

分而治之的题目与解答 在这道题的下面 

 3587. 连通图 - AcWing题库

连通性的判断 两种方法

 1.这里连通性的判断是判断连通分支是否包含所有的点。

 2.也可以不开cnt数组,直接遍历一下n个点,是否都和第一个点有公共祖先

	bool res = true;
	for(int i=2;i<=n;i++)
		if (find(i) != find(1))
		{
			res = false;
			break;
		}
	if (res) puts("YES");
	else puts("NO");

连通图—— 并查集方法

#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int p[N], cnt[N], n, m;
int a, b;
int find(int x)
{
	if (p[x] != x) p[x] = find(p[x]);
	return p[x];
}
void merge(int a, int b)
{
    a=find(a);
    b=find(b);
    if(a!=b) cnt[b]+=cnt[a];
    p[find(a)]=find(b);//注意这一行和上一行的a b前后
    //下面的写法易错
// 	if (find(a) != find(b))
// 		cnt[find(b)] += cnt[find(a)];
// 	p[find(a)] = find(b);

}

int main()
{
	while (cin >> n >> m)
	{
		for (int i = 1;i <= n;i++) p[i] = i, cnt[i] = 1;
		for (int i = 1;i <= m;i++)
		{
			cin >> a >> b;
			merge(a, b);
		}//里面有n个点则说明全通
		if (cnt[find(1)] == n) cout << "YES" << endl;
		else cout << "NO" << endl;

	}

}

 连通图——DFS

三种写法

#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
bool st[N];
const int M = 10010;
int e[M], ne[M], h[N], idx;
int n, m;

void add(int a, int b)
{
	e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
void dfs(int u)
{
	st[u] = true;
	for (int i = h[u];~i;i = ne[i])
	{
		int j = e[i];
		if (!st[j])
			dfs(j);
	}
}

int main()
{
	while (cin >> n >> m)
	{
		idx = 0;
		int flag = 0;
		memset(h, -1, sizeof h);
		memset(st, 0, sizeof st);
		while (m--)
		{
			int a, b;
			cin >> a >> b;
			add(a, b);add(b, a);
		}
		dfs(1);
		for (int i = 1;i <= n;i++)
			if (!st[i])
				flag = 1;
		if (flag) puts("NO");
		else puts("YES");
	}
}
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int n, m;
int st[N];
vector<int> v[N];
void dfs(int u)
{
	st[u] = true;
	for (auto x : v[u])
		if (!st[x])
			dfs(x);
}

int main()
{
	while (cin >> n >> m)
	{
		int flag = 0;
		memset(st, 0, sizeof st);
		for (int i = 1;i <= N - 2;i++) v[i].clear();
		while (m--)
		{
			int a, b;
			cin >> a >> b;
			v[a].push_back(b);
			v[b].push_back(a);
		}
		dfs(1);
		for (int i = 1;i <= n;i++)
			if (!st[i])
				flag = 1;
		if (flag) puts("NO");
		else puts("YES");
	}
}
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int n, m;
int st[N];
int g[N][N];

void dfs(int u)
{
	st[u] = true;
	for (int i = 1;i <= n;i++)
		if (!st[i]&& g[u][i]!=0)
			dfs(i);

}

int main()
{
	while (cin >> n >> m)
	{
		int flag = 0;
		memset(st, 0, sizeof st);
        memset(g,0,sizeof g);
		while (m--)
		{
			int a, b;
			cin >> a >> b;
			g[a][b] = 1, g[b][a] = 1;
		}
		dfs(1);
		for (int i = 1;i <= n;i++)
			if (!st[i])
				flag = 1;
		if (flag) puts("NO");
		else puts("YES");
	}
}

分而治之

题目详情 - L2-025 分而治之 (pintia.cn)

法一 

vector 邻接表,毁灭的城市标记一下,然后遍历没有被标记的城市的邻居进行判断

#include<bits/stdc++.h>
using namespace std;
const int N = 10010;
int n, m;
vector<int> v[N];
bool st[N];
int main()
{
	cin >> n >> m;
	while (m--)
	{
		int a, b;
		cin >> a >> b;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	int k;cin >> k;
	while (k--)
	{
		memset(st, false, sizeof st);
		int flag = 0;
		int cnt;
		cin >> cnt;
		for (int i = 1;i <= cnt;i++)
		{
			int tmp;cin >> tmp;
			st[tmp]=true;
		}
		for (int i = 1;i <= n;i++)
			for (int j = 0;j < v[i].size();j++)
				if (!st[i] && !st[v[i][j]])
				{
					flag = 1;
					break;
				}
		if (flag) puts("NO");
		else puts("YES");
	}
	system("pause");

}

法二

 对于并查集的做法是:对毁灭的城市进行标记,把剩下存在的路线进行并查集操作,遍历n个点进行寻找父节点,如果是本身的话就ans++  如果最后等于n则说明不连通,否则有连通分支。

for (int i = 1;i <= n;i++)
		if (f[i] == i)
            ans++;

法三

其实首先想到的是用邻接矩阵存(用g[x][y]存边),最简单但是存储超限了

以后不要考虑这个方法了,都会超时或者超限

#include<bits/stdc++.h>
using namespace std;
const int N = 10010;
int n, m;
int g[N][N], bk[N][N];
int main()
{
	cin >> n >> m;
	while (m--)
	{
		int a, b;
		cin >> a >> b;
		g[a][b] = 1, g[b][a] = 1;
	}
	int k;cin >> k;
	while (k--)
	{
		memcpy(bk, g, sizeof g);
		int flag = 0;
		int cnt;
		cin >> cnt;
		for (int i = 1;i <= cnt;i++)
		{
			int tmp;cin >> tmp;
			for (int i = 1;i <= n;i++)
				bk[tmp][i] = 0, bk[i][tmp] = 0;
		}
		for (int i = 1;i <= n;i++)
			for (int j = 1;j <= n;j++)
				if (bk[i][j])
				{
					flag = 1;
					break;
				}
		if (flag) puts("NO");
		else puts("YES");
	}
	
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/138959.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【算法】贪心算法(第四章习题解答)

4 贪心算法 4.1 若在 0−10-10−1 背包问题中, 各物品依重量递增排列时, 其价值恰好依递减序排列. 对于这个特殊的 0−10-10−1 背包问题, 设计一个有效算法找出最优解, 并说明算法的正确性. 算法设计&#xff1a;由题目所给的信息可以知道这种特殊的背包问题可以通过贪心算法…

基于多保真方法来估计方差和全局敏感度指数分析(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 此代码实现了多保真方法来估计方差和全局敏感度指数。当模型具有不确定的输入时&#xff0c;模型输出也是不确定的。基于方差的…

C++与QML混合编程

一、前言 简单来说&#xff0c;混合编程就是通过Qml高效便捷的构建UI界面&#xff0c;而使用C 来实现业务逻辑和复杂算法。Qt集成了QML引擎和Qt元对象系统&#xff0c;使得QML很容易从C 中得到扩展&#xff0c;在一定的条件下&#xff0c;QML就可以访问QObject派生类的成员&am…

112.(leaflet之家)leaflet椭圆修改

听老人家说:多看美女会长寿 地图之家总目录(订阅之前建议先查看该博客) 文章末尾处提供保证可运行完整代码包,运行如有问题,可“私信”博主。 效果如下所示: 下面献上完整代码,代码重要位置会做相应解释 <!DOCTYPE html> <html>

OpenHarmony之轻量系统编译构建流程

首先我们先来熟悉几个概念&#xff1a; - 子系统 子系统是一个逻辑概念&#xff0c;它由一个或多个具体的组件组成。OpenHarmony整体遵从分层设计&#xff0c;从下向上依次为&#xff1a;内核层、系统服务层、框架层和应用层。系统功能按照“系统 > 子系统 > 组件”逐级…

别人家的公司年终奖52个月工资-互联网企业年终裁员脸在哪

52个月工资&#xff0c;开玩笑吧&#xff0c;还真不是。据台湾媒体报道&#xff0c;中国台湾长荣海运年终奖出炉&#xff0c;继去年40个月年终奖后&#xff0c;今年再创新高&#xff0c;传言最高发放52个月年终奖金。以基层员工月薪5万新台币计算&#xff0c;表现好的员工可领到…

6.vector、set和map

一、vector 1.简介 有些时候想开一个数组&#xff0c;但是却不知道应该开多大长度的数组合适&#xff0c;因为我们需要用到的数组可能会根据情况变动。这时候我们就需要用到动态数组。 所谓动态数组&#xff0c;也就是不定长数组&#xff0c;数组的长度是可以根据我们的需要…

第四章快速排序——分而治之

分而治之&#xff08;divide and conquer,D&C&#xff09; D&C算法是递归的&#xff0c;并且有2个步骤&#xff1a; 找出基线条件&#xff0c;并且条件尽可能简单不断将问题分解&#xff0c;直到符合基线条件 给定一个数组&#xff0c;求和&#xff1a; 利用循环很容…

秒懂双向链表

目录 一、双向链表概述 二、模拟实现双向链表 1、头插法插入元素 2、尾插法插入元素 3、在指定位置插入元素 4、查询双向链表中是否包含key 5、删除第一次出现关键字为key的结点 6、删除所有值为key的结点 7、求双向链表的长度 8、遍历双向链表 9、清空双向链表 三…

【 uniapp - 黑马优购 | 商品列表 】如何实现数据获取、结构渲染、自定义组件的封装

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大二在校生&#xff0c;讨厌编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;小新爱学习. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc…

在 Mac 上将 PDF 转换为 Word 的 5 种简单方法

当谈到将PDF格式转换为Word格式时&#xff0c;用户可能会从互联网上搜索并尝试在线将PDF转换为Word。如果是这样&#xff0c;您可能会得到不好的结果并冒着文件本身的风险。在线 PDF 到 Word 转换器工具可能会产生低质量的输出&#xff0c;对文件大小有限制&#xff0c;更糟糕的…

maven多模块依赖版本不一致问题

项目结构&#xff1a; ├─springcloud-alibaba ├─.idea├─shop-common├─shop-order├─shop-product└─shop-user项目环境&#xff1a; 父工程&#xff1a; <properties><spring-cloud.version>Greenwich.RELEASE</spring-cloud.version><sprin…

java虚拟机之垃圾回收机制

一.需要回收的内存区域 程序计数器、虚拟机栈、本地方法栈 3 个区域随线程生灭(因为是线程私有)&#xff0c;栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作。而 Java 堆和方法区则不一样&#xff0c;一个接口中的多个实现类需要的内存可能不一样&#xff0c…

<Focal Loss for Dense Object Detection>论文解读

目录1.简介2.模型2.1 二阶段要比单阶段模型效果好本质原因2.2 模型结构2.3.focal loss2.3.1 公式说明2.3.2 其他2.4 消融实验3.源码详解1.简介 目标识别有两大经典结构: 第一类是以Faster RCNN为代表的二阶段识别方法&#xff0c;这种结构的第一阶段专注于proposal的提取&am…

后端开发规约

目录 项目MVC层级设计规范 工程项目模块设计 设计规约 Java编码规范 参考《阿里巴巴Java开发手册》&#xff0c;见文末参考文档 OOP 面向对象设计 & 面向接口编程 Lombok工具包依赖 Guava、Hutool 等脚手架工具包&#xff08;三方包使用其一即可&#xff09; 日志打…

python初级教程十 Mongodb增、删、改、查

Mongodb 插入文档 MongoDB 中的一个文档类似 SQL 表中的一条记录。 插入集合 集合中插入文档使用 insert_one() 方法&#xff0c;该方法的第一参数是字典 name > value 对。 以下实例向 sites 集合中插入文档&#xff1a; #!/usr/bin/python3import pymongomyclient p…

03、Java并发 Java 线程池 ( Thread Pool ) (上)

本文我们将讲解 Java 中的线程池 ( Thread Pool )&#xff0c;从 Java 标准库中的线程池的不同实现开始&#xff0c;到 Google 开发的 Guava 库的前世今生。 本章节涉及到很多前几个章节中阐述的知识点。我们希望你是按照顺序阅读下来的&#xff0c;不然有些知识会一头雾水。 J…

Redis基础篇——Redis安装以及配置文件的修改

文章目录1. 认识Redis1.1 特征1.2 安装 Redis1. 安装 Redis 依赖2. 上传安装包1.3 默认启动1.4 指定配置启动1.5 开机自启&#xff08;推荐&#xff09;1. 认识Redis Redis 诞生于 2009 年&#xff0c;全称是 Remote Dictionary Server&#xff0c;远程词典服务器&#xff0c;…

Databend 开源周报 #73

Databend 是一款强大的云数仓。专为弹性和高效设计&#xff0c;自由且开源。 即刻体验云服务&#xff1a;https://app.databend.com。 What’s New 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 Features & Improvements Multiple Catalogs …

hudi实战-- 核心点解析

目录 Hudi 基础功能 Hudi 简介 Hudi 功能 Hudi 的特性 Hudi 的 架构 Hudi 数据管理 Hudi 表数据结构 hoodie 文件 数据文件 数据存储概述 Metadata 元数据 Index 索引 索引策略 Data 数据 Hudi 核心点解析 基本概念 时间轴Timeline 文件管理 索引 Index 表的存储…