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

题意:n个人进行m轮剪刀石头布游戏(0<n<=500,0<=m<=2000),接下来m行形如x, y, ch的输入,ch='='表示x, y平局,ch='>'表示x赢y,ch='<'表示x输y, 但是我们不知道x, y的手势是什么; 其中有一个人是裁判,它可以出任意手势,其余人手势相同的分一组,共分为三组,可以存在空组,也就是说除了裁判外,其余人每一次出的手势都相同,问能不能确定裁判是几号,如果能,输出最少在第几轮可以确定;

思路:感觉此题的题意有点模糊,加上样例才勉强看懂;如果能唯一确定裁判的编号,按照格式输出编号和能确定裁判的最少轮数,如果存在一个裁判但不能确定的话输出Can not determine,如果由输入得到有多个裁判或者一个裁判都没有,那么输出Impossible; 如果顺着题目的思路去想的话,因为裁判手势可以是任意的,很难确定编号之间的相对关系;又因为除了裁判外其余人的手势是不变的,那么我们一定可以将除裁判外的人分成三组(可以有空组);想到这里我们可以发现,如果我们假设某个编号为裁判,如果除了它外其余人的关系没有矛盾,那么它就可能是裁判;此题的数据不大, 那么只要我们枚举每一个节点,假设其为裁判,如果我们得到的可能为裁判的节点唯一,那么它就是裁判,如果得到可能为裁判的节点有多个,那么就不能确定裁判,如果可能为裁判的节点一个都没有,就是Impassible啦~

现在我们已经确定的了三种情况,剩下能确定裁判的时候还要输出最少几行能确定,我们是通过排除法来确定裁判编号的,枚举每个编号为裁判,一但在某一行输入中出现矛盾,我们就确定它不是裁判,那么n-1个出现矛盾的枚举中出现矛盾最晚的那个行数即为我们能确定裁判所需的最少行数啦(因为我们要排除n-1个编号才能确定裁判的编号嘛)~

代码:

 #include <iostream>
#include <stdio.h>
#include <string.h>
#define MAXN 510
using namespace std; int rank[MAXN], pre[MAXN]; //***rank数组存储当前节点与父亲节点的关系!注意不是与根节点的关系!!! int find(int x){//**递归路径压缩
if(pre[x]!=x){
int px=find(pre[x]);
rank[x]=(rank[x]+rank[pre[x]])%; //***回溯时改变rank[x]的值,这个公式我们可以由枚举得出
pre[x]=px; //***将 x 的父亲节点变为根节点,即 x 节点直接指向根节点
}
return pre[x];
} int jion(int x, int y, int d){
int px=find(x);
int py=find(y);
if(px==py){ //***若 x, y 都已经加入并查集,即相对关系已经确定,递归压缩路径后 x, y 的根节点即为他们的父节点, 我们可以由rank得到 x, y的关系,因为我们加入并查集的 x, y的关系都是真确的,所以如果d值与我们由rank得到的关系不同,那么其为假话
if((rank[y]-rank[x]+)%!=d){ //***x, y的关系我们可以由枚举得出
return ;
}
}else{
pre[py]=px;
rank[py]=(rank[x]-rank[y]+d+)%; //***得到合并后px与py的关系,此处的公式也是可以通过枚举得出的
}
return ;
} int main(void){
int n, m;
while(~scanf("%d%d", &n, &m)){
int x[MAXN*], y[MAXN*], d;
char ch[MAXN*];
for(int i=; i<=m; i++){
scanf("%d%c%d", &x[i], &ch[i], &y[i]);
}
int tot=, flag=, gg=, jj=; //***tot统计裁判个数
for(int i=; i<n; i++){ //***枚举,假设i为裁判,若无矛盾即可行
flag=;
for(int j=; j<n; j++){ //**初始化
rank[j]=;
pre[j]=j;
}
for(int j=; j<=m; j++){ //**建立关系并查集
if(x[j]==i||y[j]==i){ //***裁判可以任意出手势,把裁判放在并查集外面
continue;
}
if(ch[j]=='='){
d=;
}else if(ch[j]=='>'){
d=;
}else{
d=;
}
if(jion(x[j], y[j], d)){ //**判断是否有矛盾
gg=max(j, gg); //**维护出现矛盾最大行数
flag=;
break;
}
}
if(flag){ //**没出现矛盾,即当前节点可以是裁判
tot++;
jj=i; //**记录裁判节点号
}
}
if(!tot){
printf("Impossible\n");
}else if(tot>){
printf("Can not determine\n");
}else{
printf("Player %d can be determined to be the judge after %d lines\n", jj, gg);
}
}
return ;
}

poj2912(种类并查集+枚举)的更多相关文章

  1. POJ2912 Rochambeau —— 种类并查集 + 枚举

    题目链接:http://poj.org/problem?id=2912 Rochambeau Time Limit: 5000MS   Memory Limit: 65536K Total Submi ...

  2. POJ 2912 Rochambeau(种类并查集+枚举)

    题目链接:http://poj.org/problem?id=2912 题目大意:n个人玩,玩石头剪刀布游戏,其中1人是裁判,剩下的n-1个人分为3组, 他们商量好了,相同组的人每次都出相同的手势,不 ...

  3. 洛谷 P1525 【关押罪犯】种类并查集

    题解 P1525 [关押罪犯]:种类并查集 前言: 在数据结构并查集中,种类并查集属于扩展域并查集一类. 比较典型的题目就是:食物链(比本题难一些,有三个种类存在) 首先讲一下本题的贪心,这个是必须要 ...

  4. 洛谷 P1525 关押罪犯 & [NOIP2010提高组](贪心,种类并查集)

    传送门 解题思路 很显然,为了让最大值最小,肯定就是从大到小枚举,让他们分在两个监狱中,第一个不符合的就是答案. 怎样判断是否在一个监狱中呢? 很显然,就是用种类并查集. 种类并查集的讲解——团伙(很 ...

  5. NOI2001|POJ1182食物链[种类并查集 向量]

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 65430   Accepted: 19283 Description ...

  6. NOIP2010关押罪犯[并查集|二分答案+二分图染色 | 种类并查集]

    题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示 ...

  7. POJ1703Find them, Catch them[种类并查集]

    Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 42416   Accepted: ...

  8. poj1417(种类并查集+dp)

    题目:http://poj.org/problem?id=1417 题意:输入三个数m, p, q 分别表示接下来的输入行数,天使数目,恶魔数目: 接下来m行输入形如x, y, ch,ch为yes表示 ...

  9. poj1733(种类并查集+离散化)

    题目链接: http://poj.org/problem?id=1733 题意: 输入n表示有一个长度为n的0,1字符串, m表示接下来有m行输入, 接下来的m行输入中x, y, even表示第x到第 ...

随机推荐

  1. Java中String和Int的相互转换

    一.将字串 String 转换成整数 intA. 有2个方法:1). int i = Integer.parseInt([String]); 或 i = Integer.parseInt([Strin ...

  2. SQL server 语句新建用户、对用户授权、删除用户实例

    Grant select on tb to db_user --给db_user用户授权 tb表 查询权限 一.命令操作 USE mydb GO --1. 新建测试用户 --1.1 添加登录用户和密码 ...

  3. JavaScript的面临的9个陷阱

    虽然不是什么很高深的技术问题,但注意一下,会使您的编程轻松些,即所谓make life easier. 笔者对某些陷阱会混杂一些评点. 1.   最后一个逗号 如这段代码,注意最后一个逗号,按语言学角 ...

  4. Svn版本控制工具的作用和应用

    一.   可解决如下问题: 1.      不小心删除了自己的项目文档和源代码文件 2.      不敢修改自己的源代码文件 3.      不知道如何把自己的项目文档传递给他人 4.      不知 ...

  5. Gunicorn 和 Nginx

    Web Application Deployment Using Nginx Nginx is a very high performant web server / (reverse)-proxy. ...

  6. iOS开发——UI进阶篇(十一)应用沙盒,归档,解档,偏好设置,plist存储,NSData,自定义对象归档解档

    1.iOS应用数据存储的常用方式XML属性列表(plist)归档Preference(偏好设置)NSKeyedArchiver归档(NSCoding)SQLite3 Core Data 2.应用沙盒每 ...

  7. UOJ52——【UR #4】元旦激光炮

    1.题目大意:就是给你三个数组啦,然后让你找到其中的第K大,但是,不可以直接访问数组,必须通过一种函数,最后的分数 是看调用几次这个函数,100次以内10分,2000以内6分.... 2.分析:最开始 ...

  8. BZOJ4196——noi2015软件包管理器

    1.题目大意:讲道理,就是让你有两个修改一个是把一个点到根的路径上的点权值全部变成1,另一个是把一个子树全部变成0 然后让你输出每次修改,改变的哪些节点的值 2.分析:就是一个树剖,树剖是满足dfs序 ...

  9. 迟来的Android的Camera开发总结

    这是好久前写的项目,但一直没有去总结.刚好在准备找工作这段时间来总结自己做过的东西,学到的东西. 写Android的自定义的相机应用时,首先要知道一些Camera开发必须知道的尺寸,不然在调试的时候, ...

  10. 剑指Offer 跳台阶

    题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法.   解题思路: f(n)=f(n-1)+f(n-2); f(1)=1,f(2)=2;   AC代码 ...