首页 > 代码库 > 【BZOJ4195】 [Noi2015]程序自动分析

【BZOJ4195】 [Noi2015]程序自动分析

Description

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

考虑一个约束满足问题的简化版本:假设x1,x2,x3,…代表程序中出现的变量,给定n个形如xi=xj或xi≠xj的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所有约束条件同时被满足。例如,一个问题中的约束条件为:x1=x2,x2=x3,x3=x4,x1≠x4,这些约束条件显然是不可能同时被满足的,因此这个问题应判定为不可被满足。
现在给出一些约束满足问题,请分别对它们进行判定。

Input

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

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

Output

输出文件包括t行。

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

Sample Input

2
2
1 2 1
1 2 0
2
1 2 1
2 1 1

Sample Output

NO
YES

HINT

 

 在第一个问题中,约束条件为:x1=x2,x1≠x2。这两个约束条件互相矛盾,因此不可被同时满足。


在第二个问题中,约束条件为:x1=x2,x2=x1。这两个约束条件是等价的,可以被同时满足。

 

1≤n≤1000000

1≤i,j≤1000000000

Solution

离散化完并查集。

Code

  1 #include <cstdio>  2 #include <cstring>  3 #include <algorithm>  4 #include <cmath>  5   6 #ifdef WIN32  7     #define LL "%I64d"  8 #else  9     #define LL "%lld" 10 #endif 11  12 #ifdef CT 13     #define debug(...) printf(__VA_ARGS__) 14     #define setfile()  15 #else 16     #define debug(...) 17     #define filename "" 18     #define setfile() freopen(filename".in", "r", stdin); freopen(filename".out", "w", stdout) 19 #endif 20  21 #define R register 22 #define getc() (_S == _T && (_T = (_S = _B) + fread(_B, 1, 1 << 15, stdin), _S == _T) ? EOF : *_S++) 23 #define dmax(_a, _b) ((_a) > (_b) ? (_a) : (_b)) 24 #define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b)) 25 #define cmax(_a, _b) (_a < (_b) ? _a = (_b) : 0) 26 #define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0) 27 #define cabs(_x) ((_x) < 0 ? (- (_x)) : (_x)) 28 char _B[1 << 15], *_S = _B, *_T = _B; 29 inline int F() 30 { 31     R char ch; R int cnt = 0; R bool minus = 0; 32     while (ch = getc(), (ch < 0 || ch > 9) && ch != -) ; 33     ch == - ? minus = 1 : cnt = ch - 0; 34     while (ch = getc(), ch >= 0 && ch <= 9) cnt = cnt * 10 + ch - 0; 35     return minus ? -cnt : cnt; 36 } 37 #define maxn 1000010 38 struct Query 39 { 40     int a, b, type; 41     inline bool operator < (const Query &that) const {return type > that.type;} 42 }q[maxn]; 43 int hash[maxn << 1], Fa[maxn << 2]; 44 int Find(R int x) {return Fa[x] == x ? x : Fa[x] = Find(Fa[x]);} 45 int main() 46 { 47 //    setfile(); 48     for (R int cas = 1, t = F(); cas <= t; ++cas) 49     { 50         R int n = F(), hashcnt = 0; 51         for (R int i = 1; i <= n; ++i) 52         { 53             q[i] = (Query) {F(), F(), F()}; 54             hash[++hashcnt] = q[i].a; 55             hash[++hashcnt] = q[i].b; 56         } 57         std::sort(hash + 1, hash + hashcnt + 1); 58         std::sort(q + 1, q + n + 1); 59         hashcnt = std::unique(hash + 1, hash + hashcnt + 1) - hash - 1; 60         for (R int i = 1; i <= (hashcnt << 1); ++i) Fa[i] = i; 61         R bool flag = 1; 62         for (R int i = 1; i <= n; ++i) 63         { 64             q[i].a = std::lower_bound(hash + 1, hash + hashcnt + 1, q[i].a) - hash; 65             q[i].b = std::lower_bound(hash + 1, hash + hashcnt + 1, q[i].b) - hash; 66 //            printf("i = %d %d %d %d\n", i, q[i].a, q[i].b, q[i].type ); 67             R int f1 = Find(q[i].a), f2 = Find(q[i].a + hashcnt); 68             R int f3 = Find(q[i].b), f4 = Find(q[i].b + hashcnt); 69             if (q[i].type == 0) 70             { 71                 if (f1 == f3 || f2 == f4) 72                 { 73                     puts("NO"); 74                     flag = 0; 75                     break; 76                 } 77             } 78             else 79             { 80                 if (f1 == f3 || f2 == f4) continue; 81                 Fa[f1] = f3; 82                 Fa[f2] = f4; 83             } 84         } 85         flag ? puts("YES") : 0; 86     } 87     return 0; 88 } 89 /* 90 1 91 9 92 24 234 1 93 2837 1 1 94 242 78 0 95 23 1 1 96 223 977 0 97 254 76 1 98 235 877 0 99 235 987 0100 877 987 0101 */

 

【BZOJ4195】 [Noi2015]程序自动分析