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();
    }
}









本文转自 小眼儿 博客园博客,原文链接:http://www.cnblogs.com/hujunzheng/p/3901530.html,如需转载请自行联系原作者
目录
相关文章
【javaSE】 实现图书管理系统
【javaSE】 实现图书管理系统
|
JSON 前端开发 安全
前端开发中的跨域问题及解决方案
在前端开发中,跨域是一个常见但又令人头疼的问题。本文将深入探讨跨域产生的原因以及一些常见的解决方案,帮助开发者更好地理解和处理跨域情况。
|
Linux
RPM软件包管理工具使用指南
RPM(Red Hat Package Manager)是Red Hat及其他基于RPM的Linux发行版中用于管理软件包的基本包管理工具。它是一个二进制包管理系统,允许用户在Linux系统中方便地安装、升级、查询和删除软件包。RPM使用.rpm文件扩展名的软件包文件,这些软件包文件包含了软件的可执行文件、配置文件、文档等,以及安装和卸载时需要执行的脚本。通过RPM,用户可以轻松地管理和维护系统中的软件,确保系统的稳定运行和软件的及时更新。
887 4
|
SQL 存储 分布式计算
❤️Hive的基本知识(一)❤️
❤️Hive的基本知识(一)❤️
202 0
7. 成功解决:io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
今天使用 Netty 搭建一个项目,接收报文时提示如下错误:`io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1`
2103 1
|
安全 PHP 缓存
网站漏洞修复之Discuz X3.4远程代码执行漏洞
近期在对discuz x3.4进行全面的网站渗透测试的时候,发现discuz多国语言版存在远程代码执行漏洞,该漏洞可导致论坛被直接上传webshell,直接远程获取管理员权限,linux服务器可以直接执行系统命令,危害性较大,关于该discuz漏洞的详情,我们来详细的分析看下。
5695 0
|
Prometheus Cloud Native Linux
Linux下安装prometheus & grafana
Linux下安装prometheus & grafana
1196 0
|
存储 编译器 C语言
c语言:文件处理操作-1
c语言:文件处理操作
123 0
|
前端开发 测试技术 API
SpringBoot-25-SpringBoot整合Swagger2以及Swagger-Bootstrap-Ui的使用
我们在之前的文章中讲过了RESTful风格设计API,没有看过的小伙伴可以查找之前的文章看一下,那么在针对这些API我们需要怎么进行测试呢?也许你会说你通过单元测试、postman、IDEA的http client
327 0

热门文章

最新文章