【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
2
1 2 1
1 2 0
2
1 2 1
2 1 1
Sample Output
NO
YES
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 0 100 877 987 0 101 */