题目描述
在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足。
考虑一个约束满足问题的简化版本:假设$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$,则该约束条件为$xi≠xj$。
输出格式
输出文件包括$t$行。
输出文件的第k行输出一个字符串“YES”或者“NO”(不包含引号,字母全部大写),“YES”表示输入中的第k个问题判定为可以被满足,“NO”表示不可被满足。
数据范围
$1≤n≤1000000$
$1≤i,j≤1000000000$
样例
输入样例:
2
2
1 2 1
1 2 0
2
1 2 1
2 1 1
输出样例:
NO
YES
并查集
什么题目要用到并查集?那就是具有非常明显的传递关系的题目,或者说并查集擅长动态维护许多具有传递性的关系,能在无向图中维护节点之间的连通性.
这道题目明显就有两个关系变量相等的约束条件和不相等的约束条件.所以说,我们就将相等的约束条件,转化为将两个变量合并到一个集合中.
那么当相等约束条件全部执行完后,记住是全部执行完毕后,我们再去看不相等约束条件,如果说发现不相等的两个变量在同一个集合,那么就是不满足问题输出NO.如果都满足了,那么就是YES!
C++ 代码
#include <bits/stdc++.h>
using namespace std;
const int N=1000000*2+10;
int a[N][3],n,m,i,j,cnt,t,fa[N],ms[N];
unordered_map<int,int> c;//建立关系表
int get(int x)
{
return fa[x]==x?x:fa[x]=get(fa[x]);//路径压缩,防止链式结构
}
void merge(int x,int y)
{
fa[get(x)]=get(y);
}
int main()
{
ios::sync_with_stdio(false);
cin>>t;
while(t--)
{
cin>>n;
n*=3;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
if (i%3)//变量i和变量j
{
if (c[x]==0)
c[x]=(++cnt);//没有出现过
a[i/3+1][i%3]=c[x];//i/3+1是第几对关系.i%3则是判断是变量i还是变量j
fa[c[x]]=c[x];
}
else//约束条件e
ms[i/3]=x;
}
int ok=0;
for(int i=1;i<=n/3;i++)
if (ms[i])//相等约束条件
merge(a[i][1],a[i][2]);
for(int i=1;i<=n/3;i++)
if (!ms[i])
{
if (get(a[i][1])==get(a[i][2]))//不相等的两个变量,发现居然相等了,那么不符合问题
{
ok=true;
cout<<"NO";
break;
}
}
if (!ok)
cout<<"YES";
cout<<endl;
}
}
怎么手动开O2啊QwQ
百度C++手动开O2
可以不用STL写吗,用离散化什么的算法可以做吗
可以的.离散化没有额外难题的.
好像 秦大佬 现在慢慢的stl用的比刚开始写题解的时候频繁多了
是的,因为我觉得STL超好用啊,所以我觉得多写有利于愉悦身心.
诶我不开O2也过了,按照您的代码把我的map改成了unordered_map就过了,这是为什么啊QwQ
因为$map$平均复杂度是$O(logN)$,但是$unordered_map$复杂度是$O(1)$。前者封装红黑树,后者封装Hash。
离散化复杂度也是nlogn啊 但过了
用map为啥不行呢 复杂度不是nlogn 吗
常数问题,开O2试一试.
存储关系不可以直接用vector< pair[HTML_REMOVED] >limit[2]来存储吗?如果e=0,就把这组关系加到limit[0]中,反之也是一样
当然可以的.
但我超时了,后来加了快读,还是超时了
开O2
vector的常数很大的.
我试一下
好的.
(及时反馈的感觉好舒服啊)你帮我解答,我肯定要即使反馈啦
hh