Rank of Tetris
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11412 Accepted Submission(s): 3267
Problem Description
自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球。
为了更好的符合那些爱好者的喜好,Lele又想了一个新点子:他将制作一个全球Tetris高手排行榜,定时更新,名堂要比福布斯富豪榜还响。关于如何排名,这个不用说都知道是根据Rating从高到低来排,如果两个人具有相同的Rating,那就按这几个人的RP从高到低来排。
终于,Lele要开始行动了,对N个人进行排名。为了方便起见,每个人都已经被编号,分别从0到N-1,并且编号越大,RP就越高。
同时Lele从狗仔队里取得一些(M个)关于Rating的信息。这些信息可能有三种情况,分别是"A > B","A = B","A < B",分别表示A的Rating高于B,等于B,小于B。
现在Lele并不是让你来帮他制作这个高手榜,他只是想知道,根据这些信息是否能够确定出这个高手榜,是的话就输出"OK"。否则就请你判断出错的原因,到底是因为信息不完全(输出"UNCERTAIN"),还是因为这些信息中包含冲突(输出"CONFLICT")。
注意,如果信息中同时包含冲突且信息不完全,就输出"CONFLICT"。
为了更好的符合那些爱好者的喜好,Lele又想了一个新点子:他将制作一个全球Tetris高手排行榜,定时更新,名堂要比福布斯富豪榜还响。关于如何排名,这个不用说都知道是根据Rating从高到低来排,如果两个人具有相同的Rating,那就按这几个人的RP从高到低来排。
终于,Lele要开始行动了,对N个人进行排名。为了方便起见,每个人都已经被编号,分别从0到N-1,并且编号越大,RP就越高。
同时Lele从狗仔队里取得一些(M个)关于Rating的信息。这些信息可能有三种情况,分别是"A > B","A = B","A < B",分别表示A的Rating高于B,等于B,小于B。
现在Lele并不是让你来帮他制作这个高手榜,他只是想知道,根据这些信息是否能够确定出这个高手榜,是的话就输出"OK"。否则就请你判断出错的原因,到底是因为信息不完全(输出"UNCERTAIN"),还是因为这些信息中包含冲突(输出"CONFLICT")。
注意,如果信息中同时包含冲突且信息不完全,就输出"CONFLICT"。
Input
本题目包含多组测试,请处理到文件结束。
每组测试第一行包含两个整数N,M(0<=N<=10000,0<=M<=20000),分别表示要排名的人数以及得到的关系数。
接下来有M行,分别表示这些关系
每组测试第一行包含两个整数N,M(0<=N<=10000,0<=M<=20000),分别表示要排名的人数以及得到的关系数。
接下来有M行,分别表示这些关系
Output
对于每组测试,在一行里按题目要求输出
Sample Input
3 3 0 > 1 1 < 2 0 > 2 4 4 1 = 2 1 > 3 2 > 0 0 > 1 3 3 1 > 0 1 > 2 2 < 1
Sample Output
OK CONFLICT UNCERTAIN
Author
linle
Source
题目大意:n个人,给出m个他们的成绩关系,看看这n个人是否严格排序,是否有环,我们运用拓扑排序可以解决这一问题,但是对于相等成绩的人我们就不好处理了(有点同学可能会被题目中的那个编号越大RP越高给迷惑,其实这个并不能参与排序),这里我们运用并查集的知识来解决就可以了,相等的我们就把他们放在一起即可,就是再进行拓扑排序的时候注意绑在一起的元素看做一个元素。
AC代码:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<math.h> #include<stdlib.h> #include<queue> #include<map> #include<set> #define bug printf("*********\n"); #define mem0(a) memset(a, 0, sizeof(a)); #define mem1(a) memset(a, -1, sizeof(a)); #define in1(a) scanf("%d" ,&a); #define in2(a, b) scanf("%d%d", &a, &b); #define out1(a) printf("%d\n", a); #define out2(a, b) printf("%d %d\n", a, b); using namespace std; typedef long long LL; typedef pair<int, int> par; const int mod = 1e9+7; const int INF = 1e9+7; const int N = 1000010; const double pi = 3.1415926; int n, m, cnt, sum; int du[10010] ,head[10010], root[10010], x[10010], y[10010]; //x记录大的,y记录小的 struct edge { int end; int next; }e[10010]; void add(int u, int v) { e[cnt].end = v; e[cnt].next = head[u]; head[u] = cnt ++; } void fmset() { for(int i = 0; i < n; i++) { root[i] = i; } } int find_root(int s) { if(s != root[s]) root[s] = find_root(root[s]); return root[s]; } void Merge(int x, int y) { if(find_root(x) == find_root(y)) return; sum --; //元素减1 root[find_root(x)] = find_root(y); } void iniset() { fmset(); mem0(du); mem1(head); cnt = 0; sum = n; } int topo() { queue<int> q; for(int i = 0; i < n; i ++) { if(du[i] == 0 && i == find_root(i)) { //因为有的元素在一起,所以我们找根节点 q.push(i); } } int s = 0; int flag = 0; while(!q.empty()) { if(q.size() > 1) flag = 1; int cur; cur = q.front(); s ++; q.pop(); for(int i = head[cur]; i != -1; i = e[i].next) { int en = e[i].end; du[en] --; if(du[en] == 0) q.push(en); } } if(s == sum) return flag; return -1; } int main() { int a, b; char str; while(~scanf("%d%d", &n, &m)) { iniset(); int ix = 0, iy = 0; for(int i = 0; i < m; i ++) { scanf("%d %c %d", &a, &str, &b); if(str == '<') { x[ix ++] = a; y[iy ++] = b; } if(str == '>') { x[ix ++] = b; y[iy ++] = a; } if(str == '=') { Merge(a, b); } } for(int i = 0; i < ix; i ++) { a = find_root(x[i]); b = find_root(y[i]); add(b, a); du[a] ++; } int k = topo(); if(k == 0) printf("OK\n"); if(k == 1) printf("UNCERTAIN\n"); if(k == -1) printf("CONFLICT\n"); } return 0; }