[NOI2015][BZOJ4195] 程序自动分析|并查集|离散化

[NOI2015][BZOJ4195] 程序自动分析|并查集|离散化

4195: [Noi2015]程序自动分析

Time Limit: 10 Sec  Memory Limit: 512 MB
Submit: 295  Solved: 150
[Submit][Status][Discuss]

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≤100000

1≤i,j≤1000000000

 

Source

NOI DAY1 T1居然是傻逼并查集……

懒得写二分了 直接上map。

离散化并查集就秒掉了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<vector>
 8 #include<map>
 9 #include<set>
10 #include<queue>
11 using namespace std;
12 map<int,int>mm;
13 int n,t,cnt,f[200005];
14 struct node { int x,y,z; } a[100005];
15 inline int read()
16 {
17     char c=getchar();
18     int a=0;
19     while (c<'0'||c>'9') c=getchar();
20     while (c>='0'&&c<='9') 
21     {
22         a=a*10+c-'0';
23         c=getchar();
24     }
25     return a;
26 }
27 inline int find(int i)
28 {
29     return f[i]==i?i:f[i]=find(f[i]);
30 }
31  
32 inline bool judge()
33 {
34     for (int i=1;i<=n;i++)
35     {
36         int p=find(mm[a[i].x]),q=find(mm[a[i].y]);
37         if (a[i].z&&p!=q) f[p]=q;
38         if (!a[i].z&&p==q) return 0;
39     }
40     return 1;
41 }
42 inline bool cmp(node a,node b)
43 {
44     return a.z>b.z;
45 }
46 int main()
47 {
48     t=read();
49     while (t--)
50     {
51         cnt=0;
52         mm.clear();
53         n=read();
54         for (int i=1;i<=n;i++)
55         {
56             a[i].x=read();
57             a[i].y=read();
58             a[i].z=read();
59             if (!mm[a[i].x]) mm[a[i].x]=++cnt;
60             if (!mm[a[i].y]) mm[a[i].y]=++cnt;
61         }
62         sort(a+1,a+n+1,cmp);
63         for (int i=1;i<=cnt;i++) f[i]=i;
64         if (judge()) puts("YES"); else puts("NO");
65     }
66     return 0;
67 }