zoukankan      html  css  js  c++  java
  • 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:
    Suspicious bugs found!
    
    ", k);
    52         }else{
    53             printf("Scenario #%d:
    No suspicious bugs found!
    
    ", 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:
    Suspicious bugs found!
    
    ", k);
    41         }else{
    42             printf("Scenario #%d:
    No suspicious bugs found!
    
    ", 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:
    Suspicious bugs found!
    
    ", k);
    51         }else{
    52             printf("Scenario #%d:
    No suspicious bugs found!
    
    ", k);
    53         }
    54     }
    55     return 0;
    56 }
  • 相关阅读:
    SQL SEREVR IO
    INTEL
    windows performance
    The DiskSpd Storage Performance Tool
    machine Learning
    NOSQL
    X64 Deep Dive
    Debugging and performance,ETW
    Disk Performance
    WCF transport-and-message-security
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/6117262.html
Copyright © 2011-2022 走看看