【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 0
100 877 987 0
101 */

 

posted @ 2017-04-09 17:07  cot  阅读(184)  评论(0编辑  收藏  举报