poj2492(種類並查集/各種解法)


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

 

題意: 有t組測試數據, 對於每組數據,第一行n, m分別表示昆蟲的數目和接下來m行x, y,

x, y表示教授判斷x, y為異性, 問教授是否有錯誤判斷,即存在x, y為同性;

 

這道題和poj1703類似, 不過更簡單一點 (poj1703題解)

 

解法1: 我們可以用rank[x]記錄x與其父親節點的關系, rank[x]=0表同性, rank[x]=1表異性;

假設前面的教授判斷都是正確的, 若后面存在與前面判斷矛盾的數據,那么教授判斷有誤;

 

代碼:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #define MAXN 2010
 4 using namespace std;  5 
 6 int rank[MAXN], pre[MAXN]; //***rank[x]存儲x與其父親節點的關系
 7 
 8 int find(int x){  //***遞歸壓縮路徑
 9     if(x!=pre[x]){ 10         int px=find(pre[x]); 11         rank[x]=(rank[x]+rank[pre[x]])%2;  //***跟新rank[x]
12         pre[x]=px; 13  } 14     return pre[x]; 15 } 16 
17 int jion(int x, int y){ 18     int px=find(x); 19     int py=find(y); 20     if(px==py){ 21         if((rank[x]+rank[y])%2==0){ //**rank得出x, y的關系為同性,又由題意得出輸入的x, y是異性, 矛盾
22             return 1; 23         }else{ 24             return 0; 25  } 26     }else{ 27         pre[py]=px; //**合並
28         rank[py]=(rank[x]+rank[y]+1)%2; //**更新rank[py]
29  } 30     return 0; 31 } 32 
33 int main(void){ 34     int t, m, n; 35     scanf("%d", &t); 36     for(int k=1; k<=t; k++){ 37         scanf("%d%d", &n, &m); 38         for(int i=0; i<=n; i++){ 39             pre[i]=i; 40             rank[i]=0; 41  } 42         int flag=0; 43         while(m--){ 44             int x, y; 45             scanf("%d%d", &x, &y); 46             if(jion(x, y)){ 47                 flag=1; 48  } 49  } 50         if(flag){ 51             printf("Scenario #%d:\nSuspicious bugs found!\n\n", k); 52         }else{ 53             printf("Scenario #%d:\nNo suspicious bugs found!\n\n", k); 54  } 55  } 56     return 0; 57 }

 

解法2:  並查集里面合並同一性別的昆蟲, 用n+x表示與x性別相反的昆蟲

 

代碼:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #define MAXN 2010
 4 using namespace std;  5 
 6 int pre[MAXN*2];  7 
 8 int find(int x){  //***遞歸壓縮路徑
 9     return x==pre[x]?pre[x]:pre[x]=find(pre[x]); 10 } 11 
12 void jion(int x, int y){//**合並
13     int px=find(x); 14     int py=find(y); 15     if(px!=py){ 16         pre[px]=py; 17  } 18 } 19 
20 int main(void){ 21     int t, m, n; 22     scanf("%d", &t); 23     for(int k=1; k<=t; k++){ 24         scanf("%d%d", &n, &m); 25         for(int i=0; i<=2*n; i++){ 26             pre[i]=i; 27  } 28         int flag=0; 29         while(m--){ 30             int x, y; 31             scanf("%d%d", &x, &y); 32             if(find(x)==find(y)){ 33                 flag=1; 34             }else{ 35                 jion(x, y+n); 36                 jion(x+n, y); 37  } 38  } 39         if(flag){ 40             printf("Scenario #%d:\nSuspicious bugs found!\n\n", k); 41         }else{ 42             printf("Scenario #%d:\nNo suspicious bugs found!\n\n", k); 43  } 44  } 45     return 0; 46 }

 

解法3: 用vis數組標記, vis[x]存儲與x性別不同的昆蟲

 

代碼:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #define MAXN 2010
 4 using namespace std;  5 
 6 int pre[MAXN*2], vis[MAXN*2];  7 
 8 int find(int x){  //***遞歸壓縮路徑
 9     return x==pre[x]?pre[x]:pre[x]=find(pre[x]); 10 } 11 
12 void jion(int x, int y){//***合並
13     int px=find(x); 14     int py=find(y); 15     if(px!=py){ 16         pre[px]=py; 17  } 18 } 19 
20 int main(void){ 21     int t, m, n; 22     scanf("%d", &t); 23     for(int k=1; k<=t; k++){ 24         scanf("%d%d", &n, &m); 25         for(int i=0; i<=2*n; i++){ 26             pre[i]=i; 27             vis[i]=0; 28  } 29         int flag=0; 30         while(m--){ 31             int x, y; 32             scanf("%d%d", &x, &y); 33             if(find(x)==find(y)){ 34                 flag=1; 35             }else if(vis[x]+vis[y]==0){ //***如果之前x, y都沒有出現
36                 vis[x]=y; 37                 vis[y]=x; 38             }else if(!vis[x]){ //***x沒有出現
39                 vis[x]=y; 40  jion(x, vis[y]); 41             }else if(!vis[y]){ //***y沒有出現
42                 vis[y]=x; 43  jion(y, vis[x]); 44             }else{ //***都出現過
45  jion(x, vis[y]); 46  jion(vis[x], y); 47  } 48  } 49         if(flag){ 50             printf("Scenario #%d:\nSuspicious bugs found!\n\n", k); 51         }else{ 52             printf("Scenario #%d:\nNo suspicious bugs found!\n\n", k); 53  } 54  } 55     return 0; 56 }

 


免責聲明!

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



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