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