POJ 2912 Rochambeau(带权并查集)
来源:互联网 发布:java用户密码加密算法 编辑:程序博客网 时间:2024/05/22 18:38
这道题纠结了一下午加一晚上,整个人都不好了,而且网上就只有一种解法,估计是题解~
自己想了一种方法无限wa,无奈耐力不够,造数据的能力也不行,不能找到bug,不能像某些偏执狂大神一样为了做出来死磕三天三夜~~~~~~~
最后用了网上的方法1a了,真是无奈。
以后有机会再研究研究。
下面是根据网上的方法写的
#include<iostream>#include<cstring>#include<algorithm>#include<cstdio>using namespace std;int father[505],Rank[505],n,m,rec[505];int query(int x) { if(x != father[x]) { int per = father[x]; father[x] = query(father[x]); Rank[x] = (Rank[x] + Rank[per] + 3) % 3; } return father[x];}struct Edge { int x,y; char c;} edge[2005];void init() { for(int i = 0;i <= n;i++) { Rank[i] = 0; father[i] = i; }}int main() { while(~scanf("%d%d",&n,&m)) { memset(rec,0,sizeof(rec)); for(int i = 0;i < m;i++) scanf("%d%c%d",&edge[i].x,&edge[i].c,&edge[i].y); for(int i = 0;i < n;i++) { init(); for(int j = 0;j < m;j++) { int x = edge[j].x; int y = edge[j].y; if(x == i || y == i) continue; char c = edge[j].c; if(c == '<') swap(x,y); int a = query(x); int b = query(y); if(a == b) { if(c == '=' && (Rank[y] - Rank[x] + 3) % 3 != 0) { rec[i] = j+1; break; } if(c != '=' && (Rank[y] - Rank[x] + 3) % 3 != 1) { rec[i] = j+1; break; } } else { father[b] = a; if(c == '=') Rank[b] = (Rank[x] - Rank[y] + 3) % 3; else Rank[b] = (Rank[x] - Rank[y] + 4) % 3; } } } int cnt = 0,k,ans = 0; for(int i = 0;i < n;i++) { if(rec[i] == 0) { k = i; cnt++; } if(rec[i] > ans) ans = rec[i]; } /*for(int i = 0;i < n;i++) printf("%d ",rec[i]); printf("\n");*/ if(cnt == 0) printf("Impossible\n"); else if(cnt == 1) printf("Player %d can be determined to be the judge after %d lines\n",k,ans); else printf("Can not determine\n"); } return 0;}这种方法难点是求后面的ans,就是最少到那条语句可以判断出谁是裁判。
这里是求有漏洞的语句的最大到哪里,后面的语句都是无用的,也就是只需要前面ans个句子就可以判断
下面是我之前的办法。
我的做法是直接并查集输入数据(i = 1~m)的时候检测漏洞,如果检查到有两个漏洞,并且两个漏洞里出现了同一个人,就说明那个人为备选裁判,再重新枚举一次检查以此人为裁判是否符合题意,最后输出。
#include<cstdio>#include<iostream>#include<algorithm>#include<cstring>using namespace std;const int maxn = 5005;int father[maxn],Rank[maxn],n,m;struct Edge { int x,y; char c;} edge[20005];int query(int x) { if(x != father[x]) { int per = father[x]; father[x] = query(father[x]); Rank[x] = (Rank[x] + Rank[per] + 3) % 3; } return father[x];}int main() { //freopen("hah.txt","r",stdin); while(~scanf("%d%d",&n,&m)) { for(int i = 0;i <= n;i++) { Rank[i] = 0; father[i] = i; } int x,y,ans = -1,ch,ni,cnt = 0,k,flag = 1; char c; for(int i = 0;i < m;i++) { scanf("%d%c%d",&edge[i].x,&edge[i].c,&edge[i].y); x = edge[i].x; y = edge[i].y; c = edge[i].c; if(c == '<') swap(x,y); int a = query(x); int b = query(y); if(a == b && flag && cnt < 2) { if((Rank[y] - Rank[x] + 3) % 3 != 0 && c == '=') cnt++; else if(c != '=' && (Rank[y] - Rank[x] + 3) % 3 != 1 && (Rank[y] - Rank[x] + 3) % 3 != -2) cnt++; if(cnt == 1) { ch = x; ni = y; } else if((ch == x && ni == y) || (ch == y && ni == x)) { cnt--; continue; } //printf("%d-%d %d\n",x,y,cnt); if(cnt == 2) { if(ch == x || ch == y) { k = i; ans = ch; } else if(ni == x || ni == y) { k = i; ans = ni; } else flag = 0; } } if(a != b && flag && cnt < 2) { father[b] = a; if(c == '=') Rank[b] = (Rank[x] - Rank[y] + 3) % 3; else Rank[b] = (Rank[x] - Rank[y] + 4) % 3; } } for(int i = 0; i <= n;i++) { Rank[i] = 0; father[i] = i; } if(ans != -1) { for(int i = 0;i < m;i++) { if(edge[i].x == ans || edge[i].y == ans) continue; int xx = edge[i].x; int yy = edge[i].y; if(edge[i].c == '<') swap(xx,yy); int a = query(xx); int b = query(yy); char cc = edge[i].c; //printf("%d %d-%d\n",ans,a,b); if(a == b) { if((Rank[yy] - Rank[xx] + 3 ) % 3 != 0 && cc == '=') { flag = 0; break; } if(cc != '=' && (Rank[yy] - Rank[xx] + 3) % 3 != 1 && (Rank[yy] - Rank[xx] + 3) % 3 != -2) { flag = 0; break; } } else { father[b] = a; if(cc == '=') Rank[b] = (Rank[xx] - Rank[yy] + 3) % 3; else Rank[b] = (Rank[xx] - Rank[yy] + 4) % 3; } } } /*for(int i = 0;i < n;i++) printf("%d-",Rank[i]); printf("\n");*/ if(n == 1 && flag) { if(cnt == 0) printf("Player 0 can be determined to be the judge after 0 lines\n"); else printf("Impossible\n"); } else { if(!flag) printf("Impossible\n"); else if(ans != -1 && flag && cnt > 1) printf("Player %d can be determined to be the judge after %d lines\n",ans,k+1); else printf("Can not determine\n"); } }}
0 0
- POJ 2912 Rochambeau(枚举+带权并查集)
- poj 2912 Rochambeau(带权并查集 + 暴力)
- poj 2912 Rochambeau(带权并查集)
- POJ - 2912 Rochambeau(带权并查集+暴力)
- POJ 2912 Rochambeau(带权并查集)
- 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 带权并差集(食物连变形)
- Apache CarbonData(from华为) :一种为更加快速数据分析而生的新Hadoop文件版式
- 关键字volatile有什么含意 并给出三个不同的例子
- Java---设计模式(单例)
- hdu 1016 Prime Ring Problem (dfs)
- 数组指针、函数指针
- POJ 2912 Rochambeau(带权并查集)
- Linux下 配置mysql Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
- java设计模式——单例模式
- 选择中医 - 感冒
- 嵌入式系统基本知识
- 选择中医 - 醒脑(养生、穴位)
- 选择中医 - 吃什么健康
- ARM
- 选择中医 - 虚寒性体质的人吃什么好(萝卜、生姜、地瓜、大蒜)