<—点个赞吧QwQ
宣传一下算法提高课整理
在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足。
考虑一个约束满足问题的简化版本:假设 $x_1,x_2,x_3,…$ 代表程序中出现的变量,给定 $n$ 个形如 $x_i=x_j$ 或 $x_i≠x_j$ 的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所有约束条件同时被满足。
例如,一个问题中的约束条件为:$x_1=x_2,x_2=x_3,x_3=x_4,x_1≠x_4$,这些约束条件显然是不可能同时被满足的,因此这个问题应判定为不可被满足。
现在给出一些约束满足问题,请分别对它们进行判定。
输入格式
输入文件的第 $1$ 行包含 $1$ 个正整数 $t$,表示需要判定的问题个数,注意这些问题之间是相互独立的。
对于每个问题,包含若干行:
第 $1$ 行包含 $1$ 个正整数 $n$,表示该问题中需要被满足的约束条件个数。
接下来 $n$ 行,每行包括 $3$ 个整数 $i,j,e$,描述 $1$ 个相等/不等的约束条件,相邻整数之间用单个空格隔开。若 $e=1$,则该约束条件为 $x_i=x_j$;若 $e=0$,则该约束条件为 $x_i≠x_j$。
输出格式
输出文件包括 $t$ 行。
输出文件的第 $k$ 行输出一个字符串 YES
或者 NO
,YES
表示输入中的第 $k$ 个问题判定为可以被满足,NO
表示不可被满足。
数据范围
$1 \le n \le 10^5$
$1 \le i,j \le 10^9$
输入样例:
2
2
1 2 1
1 2 0
2
1 2 1
2 1 1
输出样例:
NO
YES
思路
这道题是并查集的题目。
这道题中的要合并的数很大,但是只用到$2\times 10^5$个,所以我们要用离散化。
我们把所有相等的数合并在一起,最后来判断两个不相等的数是否则同一个集合里就好了。
代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int N = 200010;
int n = 200000,m;
unordered_map <int,int> mp;
int idx = 0;
struct relation {
int a,b,e;
}r[N];
int p[N];
int s (int x) {
if (mp.count (x)) return mp[x];
return mp[x] = idx++;
}
int find (int x) {
if (p[x] != x) p[x] = find (p[x]);
return p[x];
}
int main () {
int T;
cin >> T;
while (T--) {
idx = 1;
mp.clear ();
cin >> m;
for (int i = 1;i <= n;i++) p[i] = i;
for (int i = 1;i <= m;i++) {
int a,b,e;
cin >> a >> b >> e;
a = s (a),b = s (b);
r[i] = {a,b,e};
if (e) p[find (a)] = find (b);
}
bool success = true;
for (int i = 1;i <= m;i++) {
if (!r[i].e) {
int a = r[i].a,b = r[i].b;
if (find (a) == find (b)) {
success = false;
break;
}
}
}
if (success) puts ("YES");
else puts ("NO");
}
return 0;
}
这题必须离散化吗,把并查集的范围开大点应该是一个道理啊,我没写离散化,就报了个奇怪的错误,不知道咋回事
SF对吧?
数组越界了
你可以用map来写
$1e9$大小的数组你开的起吗()
开的起,MLE
为什么n不能等于N
?
3
1 2 1
1 3 0
2 3 1
不应该是错的吗,好奇怪不理解
是错的呀,他代码也确实给的是NO呀
发现了遗忘的评论(
一大早,给我整破防了,我的一个天才学弟跟我说要30天学到省队300分NOIP,仍而他现在还只会打暴力。。。。就50tps的水平把
?!
这么狂妄
他还申请停课成功了,我要跟他呆一周qwq
俺也一样
可以使用手写哈希吗
可以,就是比较麻烦
好吧
没看见下标范围,我眼瞎了
qaq
这个坐标从0 写为什么不对
因为map的初始值是0 从0开始写
对于数据
1
1
2 2 0
是过不了的
在s函数中mp=0表示的是没有赋值过 但是显然是赋值过的 所以会错
解释很对
不对吧,应该是因为从0开始会有p[0]的情况,但是p是从1到n赋值的,后面再有p[0]的情况就会被影响;