首页 > 编程语言 >P1955 [NOI2015] 程序自动分析

P1955 [NOI2015] 程序自动分析

时间:2023-11-28 19:35:00浏览次数:29  
标签:std P1955 return NOI2015 int fa 自动 findSet dt

P1955 [NOI2015] 程序自动分析

基本思路

考虑到了不等号的不可传递性,所以决定只开相等的并查集。

然后突发奇想,觉得可以在找父亲的过程中判断是不是冲突。

然而这样就不能路径压缩,显然超时。

并且,根本没看清楚数据范围,实际上这题的数很大,裸开数组会爆炸。

这是一开始的代码

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

const int N = 1e8 + 10;

int t, n;
int x, y, z;
int fa[N];

int findSet(int x)
{
	if (x == fa[x]) return x;
	return findSet(fa[x]);
}

bool check(int x, int y)
{
	if (y == fa[x]) return false;
	if (x == fa[x]) return true;
	return check(fa[x], y);
}

void merge(int x, int y)
{
	int fx = findSet(x), fy = findSet(y);
	if (fx == fy) return;
	fa[fx] = fy; 
}

int main()
{
 	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout.tie(nullptr);
	std::cin >> t;
	while(t--)
	{
		bool ok = true;
		memset(fa, 0, sizeof(fa));
		std::cin >> n;
		while(n--)
		{
			std::cin >> x >> y >> z;
			if (z == 1)
			{
				if (!fa[x]) fa[x] = x;
				if (!fa[y]) fa[y] = y;
				merge(x, y);
			}
			else if (ok) ok = (check(x, y) && check(y, x));
		}
		if (ok) std::cout << "YES\n";
		else std::cout << "NO\n";
	}
	return 0;
}

改进思路

针对超时

其实完全可以继续路径压缩,然后对于一个需要 \(x \neq y\) 的情况,直接在相等数构成的并查集里面找二者的父亲,只要相等,就说明冲突。

针对数据

离散化就行

  • 先做好基本的排序、去重。

    这里用std::unique,把重复元素都移到vector尾部。然后dt.erase(std::unique(dt.begin(), dt.end()), dt.end());来去重。

  • 然后进行离散化。

    • 本题可以离散化是因为只要区分出不同数据即可,不需要知道数据本身是什么。

    • 即按照数据在数组中第几大来给数据一个新的映射值。

    • void getLs() 
      {
      	x = lower_bound(dt.begin(), dt.end(), x) - dt.begin();
      	y = lower_bound(dt.begin(), dt.end(), y) - dt.begin();
      	fa[x] = x, fa[y] = y;
      }
      

代码实现

第一次尝试面向对象风格

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>

const int N = 1e6 + 10;

int t, n;
int fa[N];
std::vector <int> dt;

class Node{
	private:
		int findSet(int x)
		{
			return x == fa[x] ? x : fa[x] = findSet(fa[x]);
		}
	public:
		int x, y, z; 
		void read()
		{
			std::cin >> x >> y >> z;
		}
		bool operator < (const Node& rhs) const {
			return z > rhs.z;
		}
		void getLs()
		{
			x = lower_bound(dt.begin(), dt.end(), x) - dt.begin();
			y = lower_bound(dt.begin(), dt.end(), y) - dt.begin();
			fa[x] = x, fa[y] = y;
		}
		void merge()
		{
			int fx = findSet(x), fy = findSet(y);
			if (fx == fy) return;
			fa[fx] = fy; 
		}
		bool check()
		{
			return findSet(x) == findSet(y);
		}
		void outPut()
		{
			std::cout << x <<" "<< y << " " << z <<std::endl;
		}
}a[N];

int main()
{
 	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout.tie(nullptr);
	std::cin >> t;
	while(t--)
	{
		memset(fa, 0, sizeof(fa));
		bool ok = true;
		std::cin >> n;
		for (int i = 1; i <= n; i++) 
		{
			a[i].read();
			dt.push_back(a[i].x), dt.push_back(a[i].y); 
		}
		std::sort(a + 1, a + n + 1);
		std::sort(dt.begin(), dt.end());
		dt.erase(std::unique(dt.begin(), dt.end()), dt.end());
		for (int i = 1; i <= n; i++) a[i].getLs();
		for (int i = 1; i <= n; i++)
		{
			if (a[i].z) a[i].merge();
			else if (a[i].check())
			{
				ok = false;
				std::cout << "NO\n"; 
				break;
			}
		}
		if (ok) std::cout << "YES\n";
	}
	return 0;
}

标签:std,P1955,return,NOI2015,int,fa,自动,findSet,dt
From: https://www.cnblogs.com/kdlyh/p/17862770.html

相关文章

  • 软件测试/人工智能|基于录制的接口测试用例自动生成技术探究
    导言在现代软件开发中,接口测试是确保系统功能和性能的关键步骤。然而,手动编写接口测试用例往往耗费大量时间和资源。基于录制的接口测试用例自动生成技术通过简化这个流程,显著提高了测试效率和准确性。录制接口测试用例自动生成技术简介录制接口测试用例自动生成技术允许开发......
  • 软件测试/人工智能|使用 GraphWalker 实现自动化测试用例生成
    导言在软件开发中,测试是确保代码质量和稳定性的关键步骤之一。而自动生成测试用例可以大大提高测试效率和覆盖率。GraphWalker是一个基于模型的测试工具,能够帮助开发者通过定义和遍历图模型来自动生成高质量的测试用例。GraphWalker简介GraphWalker是一个开源的测试工具,它......
  • 接口自动化测试用例的设计
     做接口自动化的前提,需设计接口自动化测试用例--设计接口自动化测试用例的前提:如下一、搞清接口测试的目的: 二、搞清接口测试的优先级:三、搞清接口测试的业务逻辑和应用场景1、单接口场景的测试---如:登录2、依赖接口场景的测试---如:需先登录获取token,方能进行后续接口的......
  • E云管家开发个人微信号自动点赞朋友圈
    简要描述:朋友圈点赞请求URL:http://域名地址/snsPraise请求方式:POST请求头Headers:Content-Type:application/jsonAuthorization:login接口返回参数:参数名必选类型说明wId是String登录实例标识id是String朋友圈Id请求参数示例{"wId":"0000016e-abcd-0ea8-0002-d8c2dfdb0bf3",......
  • 自动微分
    张量的梯度信息张量的梯度信息是指张量相对于某个或多个变量的导数。梯度表示了函数在某一点的变化率,它是一个向量,其中每个元素对应于函数相对于输入变量的偏导数在深度学习中,我们通常使用梯度来更新模型参数,以便最小化或最大化某个损失函数。梯度下降是一种常见的优化算法,它使......
  • Oracle临时表会随另外一个表的创建自动提交并清空
    创建一个临时表,用它导入一些数据用这个临时表生成另外一个表,用createtable...但生成的这表总是空的。原来createtable前会进行提交commit,而临时表在commit时会自动清空(默认属性,可以改)所以生成的表总是空的。这种情况下就不要用临时表了,用普通表,因为反正用完是要手工删......
  • [办公自动化]数据分析之如何提问
    人们一想到数据分析,就想到python,想到excel。其实数据分析,最基本的是你要知道如何提问。从数据来提问,我们可以着眼于时间、数量。从时间维度,我们可以提出如下问题:1、大致就是同比、环比的概念。去年同期怎么样?上个月怎么样?2、我们可以按月度、季度、年度来对比数据。我们一年......
  • iOS-打包上架构建版本一直不出现/正在处理/自动消失
    ​iOS开发过程中,打包上架苹果审核是一个不可或缺的环节。说实话,这个问题我遇见两次了,为了让自己长点记性,决定写下来。首先,列举几种情况:1.iPa包上传至Appstore后,一个小时内不显示构建版本。(等待15分钟-25分钟是正常的)   ​ 2.“活动”栏目下,所有构建版本长时间显示“......
  • WPS 标题编号自动关联上一级变化
    1、将标题格式设置成与上一级相同 2、选中标题,设置为标题2  ......
  • homebrew学习(四)之取消homebrew自动更新
      homebrew自动更新使用brewinstall/brewcaskinstall安装软件总是先updatingHomeBrew…,速度很慢取消homebrew自动更新方法一:使用命令行,但每次重启后需要重新执行命令exportHOMEBREW_NO_AUTO_UPDATE=true方法二:如果想要重启后设置依然生效,可以把上面这行加入到......