1. 程式人生 > 實用技巧 >237. 程式自動分析 AcWing

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 }