237. 程序自动分析 AcWing

原题链接

考察: 并查集+离散化

错误思路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 }

 

2021.3.7

       二刷没做出来..错误思路是我想用带权并查集d[i] = 1表示不等,d[i] = 0表示相等.但是这是错的,相等的关系具有传递性,但是不等没有,如果a!=b,c!=b,并查集会让a与c距离 = 0,但实际是不一定相等的.这道题判定思路是将有传递关系的数据并入集合,再用无传递性的判定.

 

posted @ 2021-01-03 20:20  acmloser  阅读(82)  评论(0编辑  收藏  举报