poj1733(種類並查集+離散化)


題目鏈接: http://poj.org/problem?id=1733

 

題意: 輸入n表示有一個長度為n的0,1字符串, m表示接下來有m行輸入, 接下來的m行輸入中x, y, even表示第x到第y個字符中間1的個數為偶數個, x, y, odd表示第x到第y個字符中間1的個數為奇數個, 若m句話中第k+1是第一次與前面的話矛盾, 輸出k;

 

思路: 若x, y之間1的個數為偶數個, 那么1~x 與1~y中1的個數同奇偶性, 反之則異奇偶性, 我們可以將其理解為若輸入x, y, even, 即x, y屬於同種, 反之則屬於不同種,

用種類並查集就可以啦...不過要注意三點, 一是數據范圍1e9, 不能直接用做數組下標, 要先離散化一下; 二是輸入的數據中x, y是閉區間, 不好處理, 我們可以將其化為半開區間來處理, (x-1, y] 或者 [x, y+1); 還有就是如果全部正確的話就輸出m(這里wa了我好久~)....

 

代碼:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 #include <map>
 5 #define MAXN 5010
 6 using namespace std;  7 
 8 int rank[2*MAXN], pre[2*MAXN];  9 
10 int find(int x){  //***遞歸壓縮路徑
11     if(x!=pre[x]){ 12         int px=find(pre[x]); 13         rank[x]=rank[x]^rank[pre[x]];  //***更新rank[x]
14         pre[x]=px; 15  } 16     return pre[x]; 17 } 18 
19 int jion(int x, int y, int d){ 20     int fx=find(x); 21     int fy=find(y); 22     if(fx==fy){ 23         if(rank[x]^rank[y]!=d){ 24             return 1; 25         }else{ 26             return 0; 27  } 28     }else{ 29         pre[fy]=fx; 30         rank[fy]=(rank[x]+rank[y]+d)%2; 31  } 32     return 0; 33 } 34 
35 int main(void){ 36     map<int, int>mp; 37     int n, m, gg=0, jj=1; 38  mp.clear(); 39     scanf("%d%d", &n, &m); 40     for(int i=0; i<=2*MAXN; i++){ 41         pre[i]=i; 42         rank[i]=0; 43  } 44     for(int i=1; i<=m; i++){ 45         int x, y, d; 46         char ch[10]; 47         scanf("%d%d%s", &x, &y, ch); 48         if(!mp[x-1]){ 49             mp[x-1]=jj++; 50  } 51         if(!mp[y]){ 52             mp[y]=jj++; 53  } 54         if(strstr(ch, "even")){ 55             d=0; 56         }else{ 57             d=1; 58  } 59         if(jion(mp[x-1], mp[y], d)&&!gg){ 60             gg=i; 61  } 62  } 63     if(!gg){ 64         gg=m+1; 65  } 66     printf("%d\n", gg-1); 67     return 0; 68 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM