zoukankan      html  css  js  c++  java
  • [POJ2912]Rochambeau(并查集)

    传送门

    题意:

    n个人分成三组,玩石头剪子布游戏,同一组的人只能出同样固定的的手势,其中有一个是裁判不属于任何组,可以出任意手势,给出m个信息x op y 表示x,y是从三个组里面随机抽取的或者是裁判,他们之间的输赢关系。让你判断最少在第几组信息时,可以唯一判断出裁判,并将裁判号,以及在第几组后判断出来的输出。

    思路:
    注意这里是能够唯一确定,也就是存在确定的唯一一个裁判。那么我们可以从n个人里面枚举裁判,然后判断除去裁判之后是否还存在矛盾的关系(存在矛盾肯定是裁判在其中导致的),如果存在那么排除该人,记录在第几个信息出现的。枚举完后,如果只存在一个矛盾的人那么这个人就是裁判,如果不存在矛盾,输出Impossible,否则就表示存在多个裁判,输出Can not determine 这里存在矛盾的判断就是用分类并查集处理的了。

    ——代码

     1 #include <cstdio>
     2 #include <cstring>
     3 #define N 1000001
     4 #define max(x, y) ((x) > (y) ? (x) : (y))
     5 
     6 int n, m, k, ans, cnt;
     7 int a[N], b[N], f[N], d[N], err[N];
     8 char s[N];
     9 
    10 inline int find(int x)
    11 {
    12     if(x ^ f[x])
    13     {
    14         int fx = f[x];
    15         f[x] = find(f[x]);
    16         d[x] = (d[x] + d[fx]) % 3;
    17     }
    18     return f[x];
    19 }
    20 
    21 int main()
    22 {
    23     int i, j, fx, fy;
    24     while(~scanf("%d %d", &n, &m))
    25     {
    26         for(i = 0; i < m; i++) scanf("%d %c %d", &a[i], &s[i], &b[i]);
    27         memset(err, 0, sizeof(err));
    28         for(i = 0; i < n; i++)
    29         {
    30             for(j = 0; j < n; j++) f[j] = j, d[j] = 0;
    31             for(j = 0; j < m; j++)
    32             {
    33                 if(a[j] == i || b[j] == i) continue;
    34                 fx = find(a[j]);
    35                 fy = find(b[j]);
    36                 if(fx == fy)
    37                 {
    38                     if(s[j] == '=' && d[a[j]] ^ d[b[j]])
    39                     {
    40                         err[i] = j + 1;
    41                         break;
    42                     }
    43                     if(s[j] == '<' && (d[a[j]] - d[b[j]] + 3) % 3 != 1 && (d[b[j]] - d[a[j]] + 3) % 3 != 2)
    44                     {
    45                         err[i] = j + 1;
    46                         break;
    47                     }
    48                     if(s[j] == '>' && (d[a[j]] - d[b[j]] + 3) % 3 != 2 && (d[b[j]] - d[a[j]] + 3) % 3 != 1)
    49                     {
    50                         err[i] = j + 1;
    51                         break;
    52                     }
    53                 }
    54                 else
    55                 {
    56                     if(s[j] == '=')
    57                     {
    58                         d[fx] = (d[b[j]] - d[a[j]] + 3) % 3;
    59                         f[fx] = fy;
    60                     }
    61                     if(s[j] == '<')
    62                     {
    63                         d[fx] = (d[b[j]] - d[a[j]] + 4) % 3;
    64                         f[fx] = fy;
    65                     }
    66                     if(s[j] == '>')
    67                     {
    68                         d[fx] = (d[b[j]] - d[a[j]] + 5) % 3;
    69                         f[fx] = fy;
    70                     }
    71                 }
    72             }
    73         }
    74         k = ans = cnt = 0;
    75         for(i = 0; i < n; i++)
    76         {
    77             if(!err[i])
    78             {
    79                 cnt++;
    80                 k = i;
    81             }
    82             ans = max(ans, err[i]);
    83         }
    84         if (cnt == 0) puts("Impossible");
    85         else if (cnt == 1) printf("Player %d can be determined to be the judge after %d lines
    ", k, ans);
    86         else puts("Can not determine");
    87     }
    88 }
    View Code
  • 相关阅读:
    HDU 1124 Factorial
    hdu 1690 Bus System
    hdu 1113 Word Amalgamation
    POJ 2482 Stars in Your Window
    hdu 1385 ZOJ 1456 Minimum Transport Cost(经典floyd)
    hdu 1907 John
    VMware 虚拟机 安装 UBuntu 9.10 命令模式转换成窗口模试
    #pragma CODE_SEG __NEAR_SEG NON_BANKED详解
    Ubuntu 下Hadoop 伪分布式 hadoop0.20.2.tar.gz 的安装
    文件拷贝代码以及疑问
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/7017512.html
Copyright © 2011-2022 走看看