zoukankan      html  css  js  c++  java
  • 【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
    ", 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 */
  • 相关阅读:
    Android popupwindow 失去焦点或者点击空白区域时消失的解决方法
    九度 题目1394:五连击数组
    地市级地铁数据管理信息系统解决方式
    用位运算实现两个整数的加法运算
    Leaflet--建设移动设备友好的互动地图
    atitit.自适应设计悬浮图片的大小and 位置
    PIM-DM协议内核触发机制及协议执行机制记录
    整合struts2+spring+hibernate
    UITableViewCell的prepareForReuse方法
    《linux 内核全然剖析》编译linux 0.12 内核 Ubuntu 64bits 环境
  • 原文地址:https://www.cnblogs.com/cocottt/p/6685494.html
Copyright © 2011-2022 走看看