现在给出一些约束满足 问题,请分别 对它们进行 判定。
【输入格式】
输入文件的第 1 行包含 1 个正整数 t ,表示 ,表示 需要判定的问题个数 。注意这些 注意这些 注意这些 问题 之间 是相互独立的。 是相互独立的。 是相互独立的。
对于每个 问题 ,包含 若干行 :
第 1 行包含 1 个正整数n ,表示 该问题中需要被满足的 约束 条件 个数 。
接下来 n行,每包括 行,每包括 3 个整数 i,j,e ,描述 1 个相等 /不等的 约束 条件 ,相 邻整数之间用单个 整数之间用单个 整数之间用单个 整数之间用单个 空格隔开。 空格隔开。 空格隔开。 若 e=1 ,则 该约束条件为 该约束条件为 该约束条件为 该约束条件为 xi= xj ;若 e=0 , 则该约束条件为 xi ≠ xj
【输出格式】
输出 文件包括 t 行。
输出 文件的 第 k行输出 一个字符串“ 一个字符串“ YES ”或者 “NO ”(不包含引号,字母 (不包含引号,字母 (不包含引号,字母 (不包含引号,字母 (不包含引号,字母 (不包含引号,字母 (不包含引号,字母 全部大写) 全部大写) 全部大写) ,“YES ”表示 输入中的第 k 个问题 判定为 可以 被满足, “NO ”表示不 可被满足。
哦很久没写blog了。。本沙茶这次NOI网赛唯一全A的一题 T_T 。。
这题一眼并查集,因为等号具有传递性,将所有用等号连接的集合合并一下就行了。但是要注意只能开一个并查集来维护所有等量关系,千万不要在开一个维护不等关系!(a!=b, b!=c, 合并后会推出a!=c,然而并不一定这样)先将所有等量关系维护后,再弄依次判断不等关系是否和集合冲突即可。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 1000010; int N, T; int fa[MAXN*2]; void get(int &r) { //n很大,数据组数也多,最好加读入外挂 char c; r=0; do c=getchar(); while (c<'0'||c>'9'); do{r=r*10+c-'0';c=getchar();}while (c>='0'&&c<='9'); } int data[MAXN][2]; //记录输入数据以离散化 int b[MAXN*2]; //记录是等号还是不等号 int arr[MAXN * 2], cnt, len; int bifind(int x) { //二分查找(lower_bound比手写的慢三倍。。) int l = 1, r = len, mid = (l + r) >> 1; while (l < r) { if (arr[mid] == x) return mid; if (arr[mid] < x) l = mid + 1; else r = mid - 1; mid = (l + r) >> 1; } return mid; } struct Stack { //无聊的手写栈 int sta[MAXN*2], tp; bool empty() {return tp==0;} int top() {return sta[tp];} void push(int x) {sta[++tp]=x;} void pop() {--tp;} void clear() {tp=0;} } z; void init() { for (int i = 1; i<=len; ++i) //这里是len不是n。。n是关系的个数,len才是变量个数 fa[i] = i; } int root(int x) { //用手写栈实现的路径压缩防止递归爆栈。然而由于路径压缩的存在并不需要。。 while (fa[x] != x && x != -1) z.push(x), x = fa[x]; while (!z.empty()) fa[z.top()] = x, z.pop(); return x; } bool solve() { init(); int i, t1, t2; for (i = 1; i<=N; ++i) //先将所有相等关系合并成集合 if (b[i] == 1) { t1 = bifind(data[i][0]); t2 = bifind(data[i][1]); if (root(t1) != root(t2)) fa[root(t1)] = root(t2); } for (i = 1; i<=N; ++i) if (b[i] == 0) { t1 = bifind(data[i][0]); t2 = bifind(data[i][1]); if (root(t1) == root(t2)) //检查是否冲突 return 0; } return 1; } int main() { //freopen("prog.in", "r", stdin); //freopen("prog.out", "w", stdout); int i; get(T); while (T--) { get(N); cnt = 0; for (i = 1; i<=N; ++i) { get(data[i][0]); get(data[i][1]); get(b[i]); arr[++cnt] = data[i][0]; arr[++cnt] = data[i][1]; } sort(arr+1, arr+cnt+1); len = unique(arr+1, arr+cnt+1) - (arr+1); //len保存离散化后变量个数(重复出现不计) if (solve()) puts("YES"); else puts("NO"); } return 0; }