hdu 1811Rank of Tetris (并查集 + 拓扑排序)

/*
    题意:这些信息可能有三种情况,分别是"A > B","A = B","A < B",分别表示A的Rating高于B,等于B,小于B。

现在Lele并不是让你来帮他制作这个高手榜,他只是想知道,根据这些信息是否能够确定出这个高手榜,是的话就输出"OK"。
否则就请你判断出错的原因,到底是因为信息不完全(输出"UNCERTAIN"),还是因为这些信息中包含冲突(输出"CONFLICT")。
注意,如果信息中同时包含冲突且信息不完全,就输出"CONFLICT"。

   思路: 因为小于关系和大于关系可以转换一下位置! 这里的问题就在与如何正确的处理相等的关系!
   如果没有相等的关系,一个拓扑排序算法就可以搞定了! 既然元素相等,那么我们取相等元素中的某一个
   数来表示每一个数不是也行吗!?对,没错,用这个数来代替所有与之相等元素的数表示 '<'关系! 也就是
   转换成集合之间的关系的处理! 将每一个相等的元素集合看成一个点,这个点的代表就是集合的父亲节点! 

   那么如何来得到这个数呢?并查集最适合不过了!我们将相等的元素放入集合中!
   当 a<b时,通过getFather(a) < getFather(b)来处里a<b的关系,这里用邻接表进行处理!
*/
#include<iostream>
#include<cstring>
#include<vector>
#include<stack>
using namespace std;
int f[10005];
int rank[10005];
int n, m;
int getFather(int x){
   return x==f[x] ? x : f[x]=getFather(f[x]);
}

int Union(int a, int b){
   int fa=getFather(a), fb=getFather(b);
   if(fa!=fb){
      if(rank[fa]>rank[fb]){
         f[fb]=fa;
         rank[fa]+=rank[fb]+1;
      }
      else{
         f[fa]=fb;
         rank[fb]+=rank[fa]+1;
      }
      return 1;
   }
   return 0;
}

int in[10005];
int A[10005], B[10005];
char ch[10005];
vector<int>vx[10005];
int conflict, uncertain;
int sum;

/*void topoSort(){
    for(int j=1; j<=sum; ++j){
         int p=0, cnt=0;
         for(int i=1; i<=n; ++i)
            if(f[i]==i && in[i]==0){//f[i]==i表明 i是这个相等集合的代表元素,也就是这个集合所有元素的父节点
               p=i;
               ++cnt;
            }
         if(cnt==0){
            conflict=1;
            return;
         }
         if(cnt>1)
            uncertain=1;
         int len=vx[p].size();
         for(int i=0; i<len; ++i)
             --in[vx[p][i]];
         in[p]=-1;
    }
}*/

stack<int>ss;

void topoSort(){
    for(int i=1; i<=n; ++i)
        if(f[i]==i && in[i]==0)//f[i]==i表明 i是这个相等集合的代表元素,也就是这个集合所有元素的父节点
            ss.push(i);
    if(ss.size()==0 && sum)
        conflict=1;
    while(!ss.empty()){
         int cnt=ss.size();
         int p=ss.top();
         --sum;//表示剩余多少个节点没有排序!
         ss.pop();

         if(cnt>1)
            uncertain=1;
         int len=vx[p].size();
         for(int i=0; i<len; ++i)
             if(--in[vx[p][i]]==0)
               ss.push(vx[p][i]);
          if(ss.size()==0 && sum)
            conflict=1;
    }
} 

int main(){
    while(cin>>n>>m){
       for(int i=1; i<=n; ++i)
          f[i]=i;
       for(int i=1; i<=m; ++i){
           scanf("%d %c %d", &A[i], &ch[i], &B[i]);
           ++A[i];
           ++B[i];
           if(ch[i]=='=')
              Union(A[i], B[i]);
       }
       sum=0;
       for(int i=1; i<=n; ++i)
          if(f[i]==i)  ++sum;
       for(int i=1; i<=m; ++i){
              int fa=getFather(A[i]), fb=getFather(B[i]);//将每一个相等的元素集合看成一个点,这个点的代表就是其父亲节点
           if(ch[i]=='<'){
               vx[fa].push_back(fb);
               ++in[fb];
           }
           else if(ch[i]=='>'){
               vx[fb].push_back(fa);
               ++in[fa];
           }
       }

       conflict=uncertain=0;
       topoSort();
       if(conflict)
          cout<<"CONFLICT"<<endl;
       else if(uncertain)
             cout<<"UNCERTAIN"<<endl;
       else cout<<"OK"<<endl;
       for(int i=1; i<=n; ++i)
          vx[i].clear();

       memset(rank, 0, sizeof(int)*(n+1));
       memset(in, 0, sizeof(int)*(n+1));
       while(!ss.empty())
          ss.pop();
    }
}
时间: 2024-12-26 05:24:31

hdu 1811Rank of Tetris (并查集 + 拓扑排序)的相关文章

HDU 1829 A Bug&#039;s Life(基础种类并查集)

链接: http://acm.hdu.edu.cn/showproblem.php?pid=1829 原题: Problem Description Background Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they feature two different genders and that they only interact with b

并查集专题【完结】

个人整理 并查集 [poj] 第一题 poj 1182 食物链 点击打开链接poj 1182 思路: 带权并查集 分析: 1 典型的带权并查集的题目 2 如果x和y是同类的关系认为是0,如果是x吃y那么关系认为是1,那么x和y的关系为2就说明y吃x 3 那么如果x和y同类则rank[x] == rank[y] , 如果x吃y那么rank[x] == (rank[y]+1)%3 , 注意mod3的使用 点击查看代码 第二题 poj 1308 Is It A Tree? 点击打开链接 poj 130

HDU 1811 Rank of Tetris(拓扑排序+并查集)

链接: http://acm.hdu.edu.cn/showproblem.php?pid=1811 题目: Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想了一个新点子:他将制作一个全球Tetris高手排行榜,定时更新,名堂要比福布斯富豪榜还响.关于如何排名,这个不用说都知道是根据Rating从高到低来排,如果两个人具有相同的Rating,那就按这几个人的R

HDU 3038 How Many Answers Are Wrong? :带权并查集

链接: http://acm.hdu.edu.cn/showproblem.php?pid=3038 题目: Problem Description TT and FF are ... friends. Uh... very very good friends -________-b FF is a bad boy, he is always wooing TT to play the following game with him. This is a very humdrum game. T

HDU 2818 Building Block, poj 1988 Cube Stacking:带权并查集

链接: HDU: http://acm.hdu.edu.cn/showproblem.php?pid=2818 POJ:  http://poj.org/problem?id=1988 题目: Problem Description John are playing with blocks. There are N blocks (1 <= N <= 30000) numbered 1...N.Initially, there are N piles, and each pile contai

HDU 3938 Portal(离线+Kruskal+并查集)

链接: http://acm.hdu.edu.cn/showproblem.php?pid=3938 题目: Problem Description ZLGG found a magic theory that the bigger banana the bigger banana peel .This important theory can help him make a portal in our universal. Unfortunately, making a pair of por

HDU 2473 Junk-Mail Filter 【并查集+设立虚父节点(马甲)】

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2473 原题: Problem Description Recognizing junk mails is a tough task. The method used here consists of two steps: 1) Extract the common characteristics from the incoming email. 2) Use a filter matching t

HDU 3461:Code Lock(并查集+二分求幂)

链接: http://acm.hdu.edu.cn/showproblem.php?pid=3461 原题: Problem Description A lock you use has a code system to be opened instead of a key. The lock contains a sequence of wheels. Each wheel has the 26 letters of the English alphabet 'a' through 'z',

HDU 3047 Zjnu Stadium:带权并查集

链接: http://acm.hdu.edu.cn/showproblem.php?pid=3047 题目: Problem Description In 12th Zhejiang College Students Games 2007, there was a new stadium built in Zhejiang Normal University. It was a modern stadium which could hold thousands of people. The au