IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> codeforces CF1559D1.Mocha and Diana (Easy Version) -> 正文阅读

[开发测试]codeforces CF1559D1.Mocha and Diana (Easy Version)

题意:
MochaDiana各有一个无向图,他们的无向图都是森林,森林由一个或者多个树构成,所以森林里一定不存在环。要求向MochaDiana的森林中同时加入某条边使得他们的图依旧没有环,最多可以加入多少条这样的边。
思路:
首先对于一棵有m个节点的树来说,这棵树一定有m-1条边,并且每两个点之间都有一条路径,而且树中的任意节点父亲节点个数不会超过一个。为什么树中一定没有环呢,假设树中有环x->y->x,这个环在无向图中其实可以看为x->y的路径有两条甚至以上,那么y这个节点就有两个甚至以上的父亲节点了,和树的定义不符合,所以树中一定是无环的。又因为树种的任意两个节点之间一定有一条路径,那么你在树中添加一条边一定会构成一个环,这里就是题目解决问题的关键了,也就是说添加边不能在同一个树中添加,可以在森林中的不同树之间添加一条边。可能又会有个问题,不同树之间添加一条边不会构成环吗,不同树一开始没有相连的边,那么从一棵树的任意节点到另一棵树的任意节点必须通过这条新添加的边,并且没办法从另一条路径回到原来的点,所以一定是没有环的。
所以这里引出了解决题目的关键,在森林中不同的树之间连边。使用并查集的解决方案,森林中每棵树一个集合,然后O(n^2)遍历所有边,看看边的两个端点是否在同一个集合中,不在则添加一条边,在则无法添加。又因为是向两个森林中同时添加某条边,所以要求两个森林中这条边的两个端点都不在同一个集合中才可以添加。这种方法一定不会少了一条边,因为对每条边都进行了判断,只要两条边属于不同集合那就添加这条边,也一定不会多出来一条边,因为都是按照符合的不会构成环的情况下添加的边。
代码思路就是O(n^2)遍历所有边,然后判断这条边在两个森林中是否都属于两个不同的集合,如果都属于不同的集合那么就方案数+1,记录这条边。
代码:

#include<bits/stdc++.h>
using namespace std;
int fa1[1005],fa2[1005];//分别为Mocha和Diana的并查集
int n,m,k;//节点总数n,Mocha一开始边的数目m,Diana一开始的边数目k
int ans=0;//方案总数
struct node
{
	int x,y;
}que[1005];//答案边
void init()//初始化并查集数组
{
	for(int i=1;i<=n;i++)
	fa1[i]=i,fa2[i]=i;

}
int get1(int x)//在Mocha的森林中返回x节点属于的集合编号
{
	if(fa1[x]==x)
	return x;
	return fa1[x]=get1(fa1[x]);
}
int get2(int x)//在Diana的森林中范围x节点属于的集合编号
{
	if(fa2[x]==x)
	return x;
	return fa2[x]=get2(fa2[x]);
}
int main()
{
	
	scanf("%d%d%d",&n,&m,&k);
	init();
	for(int i=1;i<=m;i++)//构造Mocha的并查集
	{
		int x,y;
		scanf("%d%d",&x,&y);
		int fx=get1(x);
		int fy=get1(y);
		if(fx!=fy)
		fa1[fx]=fy;
	}	
	for(int i=1;i<=k;i++)//构造Diana的并查集
	{
		int x,y;
		scanf("%d%d",&x,&y);
		int fx=get2(x);
		int fy=get2(y);
		if(fx!=fy)
		fa2[fx]=fy;
	}
	for(int i=1;i<=n;i++)//N^2判断每条边是否在两个人的森林中都属于不同的集合
	for(int j=1;j<=n;j++)
	{
		int x=get1(i);//i节点在Mocha的森林中属于的集合编号
		int y=get1(j);//j节点在Mocha的森林中属于的集合编号
		int x2=get2(i);//i节点在Diana的森林中属于的集合编号
		int y2=get2(j);//j节点在Diana的森林中属于的集合编号
		if(x!=y&&x2!=y2)//在两个人的森林中都属于不同的集合
		{
			ans++;//方案数+1
			que[ans].x=i;
			que[ans].y=j;//记录边情况
			fa1[x]=y;//在Mocha的树中将(i,j)这条边连接的两个集合链接起来
			fa2[x2]=y2;//在Diana的树中将(i,j)这条边连接的两个集合链接起来
		}
	}
	//输出答案
	cout<<ans<<endl;
	for(int i=1;i<=ans;i++)
	{
		cout<<que[i].x<<" "<<que[i].y<<endl;
	}
return 0;
}
  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-08-17 15:41:40  更:2021-08-17 15:42:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/17 20:35:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码