POJ 2912 Rochambeau(枚举+加权并查集)
来源:互联网 发布:excel筛选重复数据函数 编辑:程序博客网 时间:2024/05/01 23:07
题目链接:
POJ 2912 Rochambeau
/*题意:有n个人玩石头剪刀布,有且只有一个裁判。除了裁判每个人的出拳形式都是一样的。a<b表示b打败a,a=b表示a和b出拳一样,平手。a>b表示a打败b。给出m个回合的游戏结果,问能否判断出谁是裁判?如果能还要输出是在哪个回合之后判断出谁是裁判。分析:枚举和加权并查集。对于每个人假设其为裁判,然后去掉所有和他有关的匹配,判断是否会出现矛盾。val[i]=0:i和根节点属于同一集合;val[i]=1:根节点打败i;val[i]=2:i打败根节点在寻找根节点的find()函数中,val的更新函数是:val[x]=(val[x]+val[pre[x]])%3;举个例子:找到根节点之前val[x]=1,val[pre[x]]=2:表示父节点打败x,父节点也打败父节点的父节点。(注意此时val[x]是x与父节点的关系)所以按照递归的思路,从递归倒数第二层开始pre[x]就表示为根节点了,那么pre[x]打败根节点。又因为pre[x]也打败x所以val[x]=0=(1+2)%3;递归在往上一层时pre[x]又表示为根节点了。再来看看合并操作时的val关系。fa,fb分别为aa,bb的根节点,ww是aa与bb的关系。当fa!=fb时,令pre[fa]=fb.假设val[aa]=1,即fa打败aa①,val[bb]=2,即bb打败fb②,ww=1,即bb打败aa③。则由②③的aa和fb是同一集合。再由①得fa打败fb。即val[fa]=2.也就是val[fa]=(val[bb]-val[aa]+ww)%3,但是由于有可能val[bb]-val[aa]+ww<0,所以正确的方程是:val[fa]=(val[bb]-val[aa]+ww+3)%3,当fa==fb时,那么就要判断是否出现矛盾,如果出现矛盾那么说明i不能作为裁判。判断矛盾是:(val[aa]-val[bb]+3)%3和ww是否相等。如果不矛盾,那么就接着读入输入到最后。还要注意一点就是可能会出现多个裁判,那就是Can not determine。*/#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>using namespace std;const int maxn = 510;const int maxm = 2010;int n,m,aa,bb,ww;int pre[maxn],val[maxn];int line,tmpline, ans,cnt,flag;char s;struct Read { int a, b, w;}read[maxm];void init(){ for (int i = 0; i <maxn; i++) { pre[i] = i; val[i]=0; }}int find(int x){ if(pre[x]==x) return x; int tmp=find(pre[x]); val[x]=(val[x]+val[pre[x]])%3; return pre[x]=tmp;}int main(){#ifdef LOCAL freopen("in.txt", "r", stdin); //freopen("out.txt","w",stdout);#endif while (~scanf("%d%d", &n, &m)) { if (m == 0) { //printf("case 1\n"); if(n==1) printf("Player 0 can be determined to be the judge after 0 lines\n"); else printf("Can not determine\n"); continue; } for (int i = 0; i<m; i++) { scanf("%d%c%d", &aa, &s, &bb); read[i].a=aa; read[i].b=bb; if (s == '=') read[i].w=0; else if(s=='<') read[i].w=1; else if(s=='>') read[i].w=2; } line=-1; cnt=0; for(int i=0;i<n;i++)//枚举每个人 { init(); tmpline=-1; flag=0; for(int j=0;j<m;j++) { aa=read[j].a; bb=read[j].b; ww=read[j].w; if(aa==i||bb==i) continue;//去掉i的影响看是否还会出现矛盾 int fa=find(aa); int fb=find(bb); if(fa!=fb) { pre[fa]=fb; val[fa]=(val[bb]-val[aa]+ww+3)%3; } else { if((val[aa]-val[bb]+3)%3!=ww)//出现矛盾 { tmpline=j+1;//出现矛盾所在行 flag=1; break; } } if(flag) break; } if(flag==0)//没出现矛盾 { ans=i;//i可以是裁判 cnt++; if(cnt>=2) break;//裁判数量>=2 } else line=max(line,tmpline);// } if(cnt==0) { //printf("case 2\n"); printf("Impossible\n"); } else if(cnt>=2) { //printf("case 3\n"); printf("Can not determine\n"); } else { //printf("case 4\n"); printf("Player %d can be determined to be the judge after %d lines\n",ans,line); } } return 0;}
0 0
- POJ 2912 Rochambeau(枚举+加权并查集)
- Poj-2912 Rochambeau 枚举+并查集
- POJ 2912 Rochambeau 并查集+枚举
- POJ-2912-Rochambeau [并查集][枚举]
- POJ 2912 Rochambeau(枚举+并查集)
- POJ 2912 Rochambeau(枚举+带权并查集)
- POJ 2912 Rochambeau(枚举 + 偏移量并查集)
- poj 2912 Rochambeau【枚举+种类并查集】
- poj 2912 Rochambeau(带权并查集)(枚举)
- poj 2912 - Rochambeau(并查集)
- poj 2912 Rochambeau(暴力+并查集)
- poj 2912 Rochambeau(带权并查集 + 暴力)
- poj 2912 Rochambeau(带权并查集)
- POJ 2912 Rochambeau【并查集经典应用同食物链+枚举】
- POJ 2912 Rochambeau(路径压缩并查集)
- POJ - 2912 Rochambeau(带权并查集+暴力)
- POJ 2912 Rochambeau(带权并查集)
- 7_4_C题 Rochambeau题解 [poj 2912](并查集)
- Resin
- 浅谈设计模式(一)策略模式
- CS229-17讲离散和维度灾难思路整理
- SHELL命令查找文件的方式
- NYOJ题目58-最少步数(搜索)
- POJ 2912 Rochambeau(枚举+加权并查集)
- Myeclipse配置tomcat服务器
- Picasso加载图片
- 扣丁学堂笔记第01天Android开发环境搭建
- (五)ExtJs进度条的几种实现方式
- 分享一份webdriver自动化脚本
- 对于文件的md5加密
- Java陷阱之assert关键字
- 免费资源部落的博客