题目链接:http://poj.org/problem?id=2912

Time Limit: 5000MS Memory Limit: 65536K

Description

N children are playing Rochambeau (scissors-rock-cloth) game with you. One of them is the judge. The rest children are divided into three groups (it is possible that some group is empty). You don’t know who is the judge, or how the children are grouped. Then the children start playing Rochambeau game for M rounds. Each round two children are arbitrarily selected to play Rochambeau for one once, and you will be told the outcome while not knowing which gesture the children presented. It is known that the children in the same group would present the same gesture (hence, two children in the same group always get draw when playing) and different groups for different gestures. The judge would present gesture randomly each time, hence no one knows what gesture the judge would present. Can you guess who is the judge after after the game ends? If you can, after how many rounds can you find out the judge at the earliest?

Input

Input contains multiple test cases. Each test case starts with two integers N and M (1 ≤ N ≤ 500, 0 ≤ M ≤ 2,000) in one line, which are the number of children and the number of rounds. Following are M lines, each line contains two integers in [0, N) separated by one symbol. The two integers are the IDs of the two children selected to play Rochambeau for this round. The symbol may be “=”, “>” or “<”, referring to a draw, that first child wins and that second child wins respectively.

Output

There is only one line for each test case. If the judge can be found, print the ID of the judge, and the least number of rounds after which the judge can be uniquely determined. If the judge can not be found, or the outcomes of the Mrounds of game are inconsistent, print the corresponding message.

Sample Input

  1. 3 3
  2. 0<1
  3. 1<2
  4. 2<0
  5. 3 5
  6. 0<1
  7. 0>1
  8. 1<2
  9. 1>2
  10. 0<2
  11. 4 4
  12. 0<1
  13. 0>1
  14. 2<3
  15. 2>3
  16. 1 0

Sample Output

  1. Can not determine
  2. Player 1 can be determined to be the judge after 4 lines
  3. Impossible
  4. Player 0 can be determined to be the judge after 0 lines

题意:

有n个人玩剪刀石头布,编号为0~n-1,;

其中有且仅有一个人作为裁判,而其余人分成3组(组可以为空);

这三个组分别只能出剪刀,石头和布,而裁判可以任意出;

给出m次编号为a和编号为b的猜拳结果为c,要求输出最早在知道第几次猜拳结果后可以知道裁判是哪个人。

题解:

并查集建树;

由于裁判可以任意出,所以包含裁判的边都是不可靠的,所以不能在建立关系时不能纳入裁判。

所以做法是,枚举假设裁判为第jdg个人,每次假设都进行一次并查集建树操作;

假设当前裁判编号为jdg,那么枚举m次猜拳结果时,对有他参与的直接跳过;

那么,在并查集建树过程中,会出两种情况:出现矛盾,那么这个人不是裁判;没出现矛盾,这个人是裁判(当然这是建立在有且仅有一个裁判的基础上的)。

(如果出现枚举n个人假设作为裁判,发现全部都有矛盾呢,显然这代表裁判不存在了,根据题意是要输出“Impossible”;

如果出现两个及以上的人假设作为裁判,发现都没有矛盾,那么就不能判断谁是裁判了,输出“Can not determine”;)

then,剩下的问题是,怎么知道是在知晓第几次猜拳结果后能断定谁是裁判了呢?

由于此时,枚举过程中,除去一个人(就是裁判)不会产生矛盾,剩下的n-1个人都会产生矛盾;

那么对于假设第jdg个人是裁判(但其实他并不是裁判),那么我们记录下:枚举m次猜拳结果,第一个矛盾产生的位置,记录为contradiction[jdg](也就是说在contradiction[jdg]这次之后,就知道jdg不是裁判了);

显然的,我们至少需要知晓max(contradiction[i])次猜拳结果之后,才能判断除了裁判之外的所有人都不是裁判。

AC代码:

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5. const int maxn=+;
  6. const int maxm=+;
  7.  
  8. int n,m;
  9.  
  10. int par[maxn],val[maxn]; //val[x]代表x与par[x]比:0-平局,1-输了,2-赢了。
  11. void init(int l,int r){for(int i=l;i<=r;i++) par[i]=i,val[i]=;}
  12. int find(int x)
  13. {
  14. if(par[x]==x) return x;
  15. else
  16. {
  17. int root=find(par[x]);
  18. val[x]=(val[x]+val[par[x]])%;
  19. return par[x]=root;
  20. }
  21. }
  22.  
  23. struct IN{
  24. int a,b,c;
  25. void get(char str[])
  26. {
  27. a=b=;
  28. int i;
  29. for(i=;str[i];i++)
  30. {
  31. if(str[i]=='='||str[i]=='<'||str[i]=='>')
  32. {
  33. if(str[i]=='=') c=; //a跟b比,平局
  34. if(str[i]=='<') c=; //a跟b比,赢了
  35. if(str[i]=='>') c=; //a跟b比,输了
  36. break;
  37. }
  38. a*=;
  39. a+=(str[i]-'');
  40. }
  41. for(i++;str[i];i++)
  42. {
  43. b*=;
  44. b+=(str[i]-'');
  45. }
  46. }
  47. }in[maxm];
  48.  
  49. int ctrdt[maxn]; //假设裁判为第i个人时,在第ctrdt[i]次猜拳后产生矛盾
  50.  
  51. int main()
  52. {
  53. while(scanf("%d%d%",&n,&m)!=EOF)
  54. {
  55. for(int i=;i<=m;i++)
  56. {
  57. char tmp[];
  58. scanf("%s",tmp);
  59. in[i].get(tmp);
  60. }
  61.  
  62. memset(ctrdt,,sizeof(ctrdt));
  63. for(int jdg=;jdg<n;jdg++) //枚举假设裁判为第j个人
  64. {
  65. init(,n);
  66. for(int i=;i<=m;i++)
  67. {
  68. int a=in[i].a, b=in[i].b, c=in[i].c;
  69. if(a==jdg || b==jdg) continue;
  70.  
  71. int t1=find(a),t2=find(b);
  72. if(t1!=t2)
  73. {
  74. par[t2]=t1;
  75. val[t2]=((val[a]-c+)%-val[b]+)%;
  76. }
  77. else
  78. {
  79. if( ((val[a]-c+)%-val[b]+)% != )
  80. {
  81. ctrdt[jdg]=i;
  82. break;
  83. }
  84. }
  85. }
  86. }
  87.  
  88. int cnt=,ans;
  89. int line=;
  90. for(int jdg=;jdg<n;jdg++)
  91. {
  92. if(ctrdt[jdg]==)
  93. {
  94. ans=jdg;
  95. cnt++;
  96. }
  97. else line=max(line,ctrdt[jdg]);
  98. }
  99.  
  100. if(cnt==) printf("Player %d can be determined to be the judge after %d lines\n",ans,line);
  101. else if(cnt==) printf("Impossible\n");
  102. else printf("Can not determine\n");
  103. }
  104. }

注意:并查集路径压缩时,val[]值的变动依然遵循HDU3038这篇文章中提到的向量加减规则,只是需要注意控制MOD=3,也即val[]在[0,2]内变动即可。

POJ 2912 - Rochambeau - [暴力枚举+带权并查集]的更多相关文章

  1. poj 2912 Rochambeau(枚举+带权并查集)

    题目链接:http://poj.org/problem?id=2912 题意:多个人玩石头剪刀布分成3组和一个裁判,每一组提前选定了自己出哪个手势,裁判可以随意出什么手势,问是否能够从给出的一系列石头 ...

  2. POJ 2912 Rochambeau(暴力)+【带权并查集】

    <题目链接> 题目大意: n个人进行m轮剪刀石头布游戏(0<n<=500,0<=m<=2000),接下来m行形如x, y, ch的输入,ch='='表示x, y平局 ...

  3. POJ 2912 Rochambeau(难,好题,枚举+带权并查集)

    下面的是从该网站上copy过来的,稍微改了一点,给出链接:http://hi.baidu.com/nondes/item/26dd0f1a02b1e0ef5f53b1c7 题意:有N个人玩剪刀石头布, ...

  4. POJ 1988 Cube Stacking( 带权并查集 )*

    POJ 1988 Cube Stacking( 带权并查集 ) 非常棒的一道题!借鉴"找回失去的"博客 链接:传送门 题意: P次查询,每次查询有两种: M x y 将包含x的集合 ...

  5. poj 1733 Parity game(带权并查集+离散化)

    题目链接:http://poj.org/problem?id=1733 题目大意:有一个很长很长含有01的字符串,长度可达1000000000,首先告诉你字符串的长度n,再给一个m,表示给你m条信息, ...

  6. POJ 1733 Parity game(离散化+带权并查集)

    离散化+带权并查集 题意:长度为n的0和1组成的字符串,然后问第L和R位置之间有奇数个1还是偶数个1. 根据这些回答, 判断第几个是错误(和之前有矛盾)的. 思路:此题同HDU 3038 差不多,询问 ...

  7. POJ 1988 Cube Stacking 【带权并查集】

    <题目链接> 题目大意: 有几个stack,初始里面有一个cube.支持两种操作: 1.move x y: 将x所在的stack移动到y所在stack的顶部. 2.count x:数在x所 ...

  8. POJ 1733 Parity game 【带权并查集】+【离散化】

    <题目链接> 题目大意: 一个由0,1组成的序列,每次给出一段区间的奇偶,问哪一条信息不合法. 解题分析: 我们用s[i]表示前i个数的前缀和,那么a b even意味着s[b]和s[a- ...

  9. poj 1984 Navigation Nightmare(带权并查集+小小的技巧)

    题目链接:http://poj.org/problem?id=1984 题意:题目是说给你n个线,并告知其方向,然后对于后面有一些询问,每个询问有一个时间点,要求你输出在该时间点a,b的笛卡尔距离,如 ...

随机推荐

  1. mysql临时表产生的执行效率问题改进(转)

    问题: 近日,线上MySQL查出一个慢sql,每次都要查询1000ms以上,严重影响用户体验 今得空去诊断一番,记录如下: sql原句: SELECT r.object_id AS cardId, c ...

  2. 使用session防止表单进行重复提交

    我们都知道可以通过js的方法来实现防止表单重复提交,但是js只适用于“在网络延迟的情况下让用户有时间点击多次submit按钮导致表单重复提交” 的情况下进行操作, 那如果碰到“表单提交后用户点击[刷新 ...

  3. 类型化dataset分页

    SELECT TOP (@每页行数) 所选列FROM 表名WHERE (主键 NOT IN( SELECT TOP ((@页数-1)*@每页行数) 主键FROM 表名where ( 条件)))AND ...

  4. 常见微信小程序开发工具

    图标: 1.iconfont图标库:http://www.iconfont.cn/home/index?spm=a313x.7781069.1998910419.2

  5. linux prefix

    指定安装路径不指定prefix,则可执行文件默认放在/usr /local/bin,库文件默认放在/usr/local/lib,配置文件默认放在/usr/local/etc.其它的资源文件放在/usr ...

  6. springbatch---->springbatch的使用(四)

    这里我们重点学习一下springbatch里面的各种监听器的使用,以及job参数的传递.追求得到之日即其终止之时,寻觅的过程亦即失去的过程. springbatch的监听器 一.JOB LISTENE ...

  7. c++ map使用问题【运行结果不一样】

    map经常把指针作为key,这种情况下. 我们经常会很自然的以为,如果要取元素时,会按照我们存的顺序拿到元素. 但是事实上不是这样的,因为map取得时候是按key的大小排序的,而如果用指针作为key, ...

  8. JS - 常用效果代码库 (四)

    1.首字母大写示例: var value = “一段文本或一个参数”; value = value.toString() return value.charAt(0).toUpperCase() + ...

  9. Android 缓存策略demo

    packageinstaller\permission\model\PermissionApps.java /** * Class used to reduce the number of calls ...

  10. vs2017编译网狐荣耀服务端的心得

    1.找不到d3dx9.h 从D:\Microsoft DirectX SDK (June 2010)\Include复制 d3dx9.hd3dx9anim.hd3dx9core.hd3dx9effec ...