据说考前写题解可以$\text{RP}$++?

这题还是算一道并查集水题了吧qwq我又做了好久

--------------------------------------------------------

题目描述

在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足。

考虑一个约束满足问题的简化版本:假设$x_1$,$x_2$,$x_3$...代表程序中出现的变量,给定$\text{n}$个形如$x_i=x_j$或$x_i≠x_j$的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所有约束条件同时被满足。例如,一个问题中的约束条件为:$x_1=x_2$,$x_2=x_3$,$x_3=x_4$,$x_4≠x_1$,这些约束条件显然是不可能同时被满足的,因此这个问题应判定为不可被满足。

现在给出一些约束满足问题,请分别对它们进行判定。

输入格式

输入文件的第$1$行包含$1$个正整数$\text{t}$,表示需要判定的问题个数。注意这些问题之间是相互独立的。

对于每个问题,包含若干行:

第$1$行包含$1$个正整数$\text{n}$,表示该问题中需要被满足的约束条件个数。接下来$\text{n}$行,每行包括$3$个整数$\text{i,j,e}$,描述$1$个相等/不等的约束条件,相邻整数之间用单个空格隔开。若$\text{e=1}$,则该约束条件为$x_i=x_j$;若$\text{e=0}$,则该约束条件为$x_i≠x_j$;

输出格式

输出文件包括$\text{t}$行。

输出文件的第 $\text{k}$行输出一个字符串“$\text{YES}$” 或者“$\text{NO}$”(不包含引号,字母全部大写),“$\text{YES}$” 表示输入中的第$\text{k}$个问题判定为可以被满足,“$\text{NO}$” 表示不可被满足。

------------------------------------------------------------

题目要求判断多个等式和不等式是否矛盾。

由于多个等式具有传递性,所以会想到用并查集来维护变量之间的关系。

如果当前数据无解,那么显然是出现了多个等式间接满足$\text{x=y}$,但是题目中又出现$\text{x≠y}$的条件。

所以,对于每一组$\text{x=y}$的约束条件,合并这两个元素,代表这两个元素满足相等关系。

如果出现$\text{x≠y}$的约束条件,检查这两个元素是否在并查集中,如果是,就输出无解;否则继续判断,直到判断完所有的条件。

中间过程有一些细节处理需要注意一下:(也是自己遇到的问题,当然这里有可能是我没有想到用什么更好的办法去处理)

$\text{1.}$ 题目数据范围中的$\text{i,j}$很大,数组肯定装不下,所以可以离散化处理;

$\text{2.}$ 我们的程序中,如果有两个条件互相约束且满足一定的顺序(比如说第一行$\text{x=y}$,第二行$\text{x≠y}$),那么我们的程序还可以正常输出;但是如果将这两行交换一下输入顺序,程序就会输出错误的答案。一开始我想的是另外一个并查集来维护不等式之间的关系,但是后来发现不等式没有传递性...所以我们可以考虑优先处理变量相等的关系,然后再来处理变量不相等的关系,这样就可以保证查询不相等变量是否连通时不会受到后面关系的影响。

概括一下就是:要优先处理相等变量之间的关系,保证不会影响后面不相等变量之间的关系。

$\text{3.}$ 由于有$\text{n}$对关系,每对关系又有$\text{2}$个变量,所以并查集数组的大小一定要开两倍!

上代码~

#include <cstdio>
#include <algorithm> using namespace std; const int N = 1e6 + 5; int t, n, tot, cnt;
int fa[N << 1], a[N << 1], temp[N << 1]; struct node {
int x, y;
bool z;
} ask[N];//存储查询 inline int get (int x) {
if (x == fa[x]) return x;
return fa[x] = get(fa[x]);
} inline void merge (int x, int y) {
fa[get(x)] = get(y);
} inline bool tmp (node g, node h) {
return g.z > h.z;
} inline void solve () {
scanf("%d", &n);
tot = cnt = 0;
for (int i = 1; i <= n * 2; i++) fa[i] = i;//数组大小一定要开两倍啊
for (int i = 1; i <= n; i++) {
scanf("%d%d%d", &ask[i].x, &ask[i].y, &ask[i].z);
temp[++tot] = ask[i].x;
temp[++tot] = ask[i].y;
}
sort(temp + 1, temp + tot + 1);
sort(ask + 1, ask + n + 1, tmp);//对查询排序,保证优先处理相等变量之间的关系
a[++cnt] = temp[1];
for (int i = 2; i <= tot; i++) {
if (temp[i] != temp[i - 1]) a[++cnt] = temp[i];
}//离散化输入的变量
for (int i = 1; i <= n; i++) {
int xx = lower_bound(a + 1, a + cnt + 1, ask[i].x) - a;
int yy = lower_bound(a + 1, a + cnt + 1, ask[i].y) - a;
if (ask[i].z) merge(xx, yy);
else {
if (get(xx) == get(yy)) {
printf("NO\n");
return;
}//如果前面满足相等关系但是这里又满足不等关系,无解
}
}
printf("YES\n");
} int main () {
scanf("%d", &t);
while (t--) solve();
return 0;
}

题解 [NOI2015]程序自动分析的更多相关文章

  1. codevs4600 [NOI2015]程序自动分析==洛谷P1955 程序自动分析

    4600 [NOI2015]程序自动分析  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 黄金 Gold 题解  查看运行结果     题目描述 Description 在实现 ...

  2. 【BZOJ4195】[Noi2015]程序自动分析 并查集

    [BZOJ4195][Noi2015]程序自动分析 Description 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3 ...

  3. bzoj 4195: [Noi2015]程序自动分析

    4195: [Noi2015]程序自动分析 Description 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3,…代表 ...

  4. [UOJ#127][BZOJ4195][NOI2015]程序自动分析

    [UOJ#127][BZOJ4195][NOI2015]程序自动分析 试题描述 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2, ...

  5. Codevs 4600 [NOI2015]程序自动分析

    4600 [NOI2015]程序自动分析 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 传送门 题目描述 Description 在实现程序自动分析的过程中,常常需 ...

  6. BZOJ4195 [Noi2015]程序自动分析(离散化+并查集)

    4195: [Noi2015]程序自动分析 Time Limit: 10 Sec  Memory Limit: 512 MB Submit: 689  Solved: 296 [Submit][Sta ...

  7. BZOJ4195 NOI2015 程序自动分析

    4195: [Noi2015]程序自动分析 Time Limit: 10 Sec Memory Limit: 512 MB Description 在实现程序自动分析的过程中,常常需要判定一些约束条件 ...

  8. [NOI2015]程序自动分析(并查集,离散化)

    [NOI2015]程序自动分析 Description 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3,-代表程序中出现的 ...

  9. 【bzoj4195】[Noi2015]程序自动分析 离散化+并查集

    题目描述 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3,…代表程序中出现的变量,给定n个形如xi=xj或xi≠xj的变量 ...

随机推荐

  1. python 迭代器(一):迭代器基础(一) 语言内部使用 iter(...) 内置函数处理可迭代对象的方式

    简介 在 Python 中,所有集合都可以迭代.在 Python 语言内部,迭代器用于支持: 1.for 循环2.构建和扩展集合类型3.逐行遍历文本文件4.列表推导.字典推导和集合推导5.元组拆包6. ...

  2. Java对象与Json字符串的转换

    Java对象与Json字符串的转换 JSON是一种轻量级的数据交换格式,常用于前后端的数据交流 后端 : 前端 Java对象 > JsonString Java对象 < jsonStrin ...

  3. 对Vue中的MVVM原理解析和实现

    对Vue中的MVVM原理解析和实现 首先你对Vue需要有一定的了解,知道MVVM.这样才能更有助于你顺利的完成下面原理的阅读学习和编写 下面由我阿巴阿巴的详细走一遍Vue中MVVM原理的实现,这篇文章 ...

  4. 开会时CPU 飙升100%同事们都手忙脚乱记一次应急处理过程

    告警 正在开会,突然钉钉告警声响个不停,同时市场人员反馈客户在投诉系统登不进了,报504错误.查看钉钉上的告警信息,几台业务服务器节点全部报CPU超过告警阈值,达100%. 赶紧从会上下来,SSH登录 ...

  5. kafka零拷贝

    Kafka之所以那么快的另外一个原因就是零拷贝(zero-copy)技术.本文我们就来了解Kafka中使用的零拷贝技术为什么那么快. 传统的文件拷贝 传统的文件拷贝通常需要从用户态去转到核心态,经过r ...

  6. 跳过Google开机设置/验证/向导

    Google 的开机设置向导,亦或称作开机验证,对于刷机党来说最熟悉不过了.一般情况下,刷类原生或是原生系统,再刷 Gapps,开机就需要进行一些 Google 验证.这些验证,与国内的手机厂商所设置 ...

  7. Sharding-Proxy的基本功能使用

    Sharding-Proxy是一个分布式数据库中间件,定位为透明化的数据库代理端.作为开发人员可以完全把它当成数据库,而它具体的分片规则在Sharding-Proxy中配置.它的整体架构图如下: 在架 ...

  8. 【JVM之内存与垃圾回收篇】StringTable

    StringTable String的基本特性 String:字符串,使用一对 "" 引起来表示 String s1 = "Nemo"; // 字面量的定义方式 ...

  9. 异常类throwable

    一.Error 严重错误,系统内部的错误.无法通过处理,只能避免. 二.Exception 使用不当导致,是可以避免的. 异常分类: 1.编译时异常 编译时遇到的异常,若未处理,就会编译失败,必须进行 ...

  10. 乌班图16 配置nginx

    阿里云 乌班图16 安装ngnix sudo apt install nginx nginx 启动 重启 关闭 sudo service nginx start restart stop status ...