考察: 并查集+离散化
错误思路1:
在线处理,每次收到新的命令就判断对错,不知道在线处理能不能行,但是在线有个麻烦的点是要判断这个数字是否在alls里面出现过,如果出现过判断多错,没有就是要新加入关系.并且在线处理还需要标记哪些变量不能相等
错误思路2:
将1~N的数字全部赋值p[i] = i,这样程序在某个测试点会报错,原因暂时未知,但是这种思想明显可以优化
正确思路:
离线处理,本题判对和判错的唯一矛盾点在本该相等的数说不等,或者本该不等的数说相等,这里处理第一个矛盾更方便,因为没有用过的数本就不等.我们可以将相等元素全部纳入集合,在不等的集合里判断
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef pair<int,int> pii; 4 const int N = 2000010; //一个问题两个数 5 vector<int> alls; 6 vector<pii> nequ,equ; 7 int p[N]; 8 int fp(int x) 9 { 10 if(p[x]!=x) p[x] = fp(p[x]); 11 return p[x]; 12 } 13 int fi(int x) 14 { 15 return lower_bound(alls.begin(),alls.end(),x)-alls.begin(); 16 } 17 void merge(int x,int y) 18 { 19 p[fp(p[x])] = fp(y); 20 } 21 int main() 22 { 23 // freopen("in.txt","r",stdin); 24 int n; 25 scanf("%d",&n); 26 while(n--) 27 { 28 bool flag = false; 29 alls.clear(); equ.clear(); nequ.clear(); 30 int x; scanf("%d",&x); 31 while(x--){ 32 int i,j,e; 33 scanf("%d%d%d",&i,&j,&e); 34 if(e){ 35 alls.push_back(i); alls.push_back(j); 36 equ.push_back({i,j}); 37 }else{ 38 alls.push_back(i); alls.push_back(j); 39 nequ.push_back({i,j}); 40 } 41 } 42 sort(alls.begin(),alls.end()); 43 alls.erase(unique(alls.begin(),alls.end()),alls.end()); 44 for(int i=0;i<alls.size();i++) p[i] = i; 45 for(int i=0;i<equ.size();i++){ 46 pii t = equ[i]; 47 int xi = fi(t.first); int yi = fi(t.second); 48 merge(xi,yi); 49 } 50 for(int i=0;i<nequ.size();i++){ 51 pii t = nequ[i]; 52 int xi = fi(t.first); int yi = fi(t.second); 53 int px = fp(xi); int py = fp(yi); 54 if(px==py){ 55 flag = true; 56 printf("NO\n"); 57 break; 58 } 59 } 60 if(!flag) printf("YES\n"); 61 } 62 return 0; 63 }