题目
HDU1811Rank of Tetris
自从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"。
Input
本题目包含多组测试,请处理到文件结束。
每组测试第一行包含两个整数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
错误点
1.一开始想的是,使用大于号,反正号码大的在前面,直接大于号不行吗?然后题目tm问的是合不合法,啊。。。
2.要 先 “生成并查集” 再 “建立图”,不然的话,当,一个并查集联通里面的头头的in[k] = 0,很难确定到底是push它,还是它小弟呢?是不是应该包括它和他小弟(并查集内全部)都push进去?但是你都push进去,万一他们数量大于1,queue的size>1,那就直接不可能是OK了。就这一点,卡了我半天我靠。。。啊。。。。
AC代码
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int N = 2e4 + 1e3;
vector<int> vec[N];
int n , m , in[N], path[N] ,ques[N] , ques1[N];
void init(){
for(int i = 0 ; i <= n ; i ++ ){
vec[i].clear();
in[i] = 0;path[i] = i;ques[i] =0;ques1[i]=0;
}
}
int find(int num){
if(num == path[num]) return num;
else{
num = find(path[num]);
return num;
}
}
void add(int a, int b){
int fa = find(a);
int fb = find(b);
if(fa != fb){
path[fa] = fb;
}
}
void renew(){//曾经用来重新更新in的函数,对于答案没有用处~
int i ;
for(i = 0 ; i < n ; i ++ ){
if(i!=find(i)){
in[find(i)] += in[i];
}
}
}
int topSort(){
int i , j , flag = 1;
int cnt = 0 , index = 0;
queue<int> que;
for(j = 0 ; j < n ; j ++ ){
int k = find(j);
if(j == k && in[k] == 0){
que.push(k);
}
}
while(que.size()){
if(que.size() > 1) flag = 0;
index = que.front();
que.pop();
for(j = 0 ; j < vec[index].size() ; j ++ ){
int v = find(vec[index][j]);
in[v]--;
if(in[v] == 0 ) que.push(v);
}
}
for(j = 0 ; j < n ; j ++ ){
if(j == find(j)&&in[j]>0) return -1;
}
return flag;
}
int main(){
std::ios::sync_with_stdio(false);
int i , j , a , b , cnt;
char ope;
bool exflag = false;
while(cin>>n>>m){
cnt = 1;
exflag = false;
init();
for(i = 1 ; i <= m ; i ++ ){
cin>>a>>ope>>b;
switch(ope){
case '>':{
ques[cnt] = a;
ques1[cnt++] = b;
break;
}
case '<':{
ques[cnt] = b;
ques1[cnt++] = a;
break;
}
case '=':{
add( a , b );
break;
}
}
}
for(i = 1 ; i < cnt ; i ++ ){
int u = find(ques[i]);
int v = find(ques1[i]);
if(u == v){
exflag = true;
}else{
vec[u].push_back(v);
in[v] ++;
}
}
if(exflag){
cout<<"CONFLICT"<<endl;continue;
}
int flag = topSort();
if(flag == -1){
cout<<"CONFLICT"<<endl;
}else if(flag == 1){
cout<<"OK"<<endl;
}else{
cout<<"UNCERTAIN"<<endl;
}
}
return 0;
}
我要写一个惨字