poj2912(种类并查集+枚举)
题目: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(种类并查集+枚举)的更多相关文章
- POJ2912 Rochambeau —— 种类并查集 + 枚举
题目链接:http://poj.org/problem?id=2912 Rochambeau Time Limit: 5000MS Memory Limit: 65536K Total Submi ...
- POJ 2912 Rochambeau(种类并查集+枚举)
题目链接:http://poj.org/problem?id=2912 题目大意:n个人玩,玩石头剪刀布游戏,其中1人是裁判,剩下的n-1个人分为3组, 他们商量好了,相同组的人每次都出相同的手势,不 ...
- 洛谷 P1525 【关押罪犯】种类并查集
题解 P1525 [关押罪犯]:种类并查集 前言: 在数据结构并查集中,种类并查集属于扩展域并查集一类. 比较典型的题目就是:食物链(比本题难一些,有三个种类存在) 首先讲一下本题的贪心,这个是必须要 ...
- 洛谷 P1525 关押罪犯 & [NOIP2010提高组](贪心,种类并查集)
传送门 解题思路 很显然,为了让最大值最小,肯定就是从大到小枚举,让他们分在两个监狱中,第一个不符合的就是答案. 怎样判断是否在一个监狱中呢? 很显然,就是用种类并查集. 种类并查集的讲解——团伙(很 ...
- NOI2001|POJ1182食物链[种类并查集 向量]
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 65430 Accepted: 19283 Description ...
- NOIP2010关押罪犯[并查集|二分答案+二分图染色 | 种类并查集]
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示 ...
- POJ1703Find them, Catch them[种类并查集]
Find them, Catch them Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 42416 Accepted: ...
- poj1417(种类并查集+dp)
题目:http://poj.org/problem?id=1417 题意:输入三个数m, p, q 分别表示接下来的输入行数,天使数目,恶魔数目: 接下来m行输入形如x, y, ch,ch为yes表示 ...
- poj1733(种类并查集+离散化)
题目链接: http://poj.org/problem?id=1733 题意: 输入n表示有一个长度为n的0,1字符串, m表示接下来有m行输入, 接下来的m行输入中x, y, even表示第x到第 ...
随机推荐
- linux 下恢复后台程序的方法
一直以为这个东西不怎么重要,所以一直没怎么去记,已经第三次百度了,不想再有第四次. 如果你在终端下运行一个程序,如果这个程序正在运行,我们可以用 ctrl + z 的命令将这个程序挂到后台. desk ...
- 数据流图DFD画法
数据流图(DFD- Data Flow Diagram)让系统分析者弄清楚"做什么"的问题,其重要性就不言而喻了.那么我们怎么画数据流图呢?数据流图与系统流程图又有什么区别呢? 步 ...
- HDU 1710 二叉树三种遍历
Binary Tree Traversals Problem Description A binary tree is a finite set of vertices that is either ...
- ndk学习5: ndk中使用c++
默认情况下ndk不支持标准C++库,异常, rtti等 在ndk文档有关于C++ support的详细介绍 一. 使用C++标准库 介绍: 默认是使用最小额度的C++运行时库, 在Applic ...
- yum服务器搭建(深入理解yum工作原理)
作者:firefoxbug 时间:July 27, 2014 分类:Linux 前言 在前面一篇rpm包制作描述了rpm的打包过程,这篇文章主要讲述yum的工作原理. yum 运行原理 yum的工作需 ...
- 【架构】Google的大规模集群管理工具Borg
参考资料: http://www.cnblogs.com/YaoDD/p/5374393.html http://www.cnblogs.com/YaoDD/p/5351589.html
- crontab命令
前一天学习了 at 命令是针对仅运行一次的任务,循环运行的例行性计划任务,linux系统则是由 cron (crond) 这个系统服务来控制的.Linux 系统上面原本就有非常多的计划性工作,因此这个 ...
- [k]web页面-browser兼容问题-1
1:空的a标签在IE7/8下不能点击(2015-05-22) html代码: <ul class='oUl'><li><a href="#"> ...
- SHAREPOINT - CAML列表查询
首先要了解的是CAML(Collaboration Application Markup Language)不仅仅是用在对列表.文档库的查询,字段的定义,站点定义等处处使用的都是CAML. 简单的提一 ...
- (转载)让XCode运行时自动更新资源
转自http://goldlion.blog.51cto.com/4127613/1351616 用过XCode的人都知道,XCode有一个臭名昭著的bug——除非你修改了源代码造成了重新编译,否则游 ...