zoukankan      html  css  js  c++  java
  • 【HDOJ1811】【并查集预处理+拓扑排序】

    http://acm.hdu.edu.cn/showproblem.php?pid=1811

    Rank of Tetris

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 11382    Accepted Submission(s): 3261

    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"。
     
    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
    题目大意:给一堆点的关系【大于小于或等于】让判断这些点之间的关系是否明确【任何两个点的关系都能确定】且正确【不会出现冲突】
    题目分析:首先预处理:大于和小于容易处理,直接当作有向边就行,而等于应用并查集进行预处理使等于的关系点缩成连通块【这和强连通分量Tarjan缩点类似】,
         预处理完之后将各连通块按照关系进行有向连接,
         最后根据入度、出度以及拓扑序列中点的个数来确定是否正确。
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<queue>
      5 using namespace std;
      6 queue<int>pq;
      7 struct edge{
      8     int to;
      9     int next;
     10 }EDGE[20005];
     11 struct pot{
     12     int to1;
     13     int to2;
     14     char ch;
     15 }POT[20005];
     16 int cnt=0;    
     17 int flag;
     18 int in[10005],head[10005],pre[10005],vis[10005],vviss[10005],vvis[10005],out[10005];
     19 int n,m,N;
     20 void add(int x,int y)
     21 {
     22     in[y]++;
     23     out[x]++;
     24     EDGE[cnt].to=y;
     25     EDGE[cnt].next=head[x];
     26     head[x]=cnt++;
     27 }
     28 int orz1=0,orz2=0;
     29 int find(int x)
     30 {
     31     int xx=x;
     32     while(x!=pre[x])
     33     {
     34         x=pre[x];
     35     }
     36     while(pre[xx]!=x)
     37     {
     38         int t=pre[xx];
     39         pre[xx]=x;
     40         xx=t;
     41     }
     42     return x;
     43 }
     44 void Topsort()
     45 {
     46     int wqw=0;
     47     for(int i = 0 ; i < N ; i++)
     48     {
     49         if(!in[find(i)]&&!vis[find(i)])
     50         {
     51             wqw++;
     52             orz2++;
     53             vis[find(i)]=1;
     54             pq.push(find(i));
     55         }
     56     }
     57     if(wqw>1)flag=2;
     58     while(!pq.empty())
     59     {
     60         int qwq=pq.front();pq.pop();
     61         for(int i = head[qwq];i != -1 ; i=EDGE[i].next)
     62         {
     63             int v=EDGE[i].to;
     64             in[v]--;
     65             if(!in[v])
     66             {
     67                 orz2++;
     68                 pq.push(v);
     69             }
     70         }
     71     }
     72 }
     73 int main()
     74 {
     75     while(scanf("%d%d",&n,&m)==2)
     76     {
     77         N=n;
     78         orz1=0;orz2=0;
     79         memset(head,-1,sizeof(head));
     80         memset(vis,0,sizeof(vis));
     81         memset(vvis,0,sizeof(vvis));
     82         memset(vviss,0,sizeof(vviss));
     83         memset(in,0,sizeof(in));
     84         memset(out,0,sizeof(out));
     85         for(int i = 0 ; i < n ; i++)pre[i]=i;
     86         for(int i = 0 ; i < m; i++)
     87         {
     88             int a,c;
     89             char b;
     90             scanf("%d %c %d",&POT[i].to1,&POT[i].ch,&POT[i].to2);
     91             if(POT[i].ch=='=')
     92             {
     93                 if(find(POT[i].to1)!=find(POT[i].to2))
     94                 {
     95                     pre[find(POT[i].to1)]=find(POT[i].to2);
     96                     n--;
     97                 }
     98             //    vviss[find(POT[i].to2)]=1;
     99             }    
    100         }
    101         flag=0;
    102     for(int i = 0 ; i < m ; i++)
    103     {
    104         if(POT[i].ch=='=')
    105         continue;
    106         char b=POT[i].ch;
    107         int a=find(POT[i].to1);
    108         int c=find(POT[i].to2);
    109         if(a!=c)
    110         {
    111             if(b=='>')
    112                 add(a,c);
    113                 else if(b=='<')
    114                 add(c,a);        
    115         
    116         }
    117         else
    118         flag=3;
    119     }
    120     int qwq=0;
    121     if(flag!=3)
    122     {
    123     for(int i = 0 ; i < N ; i++)
    124     {
    125         if(!out[find(i)]&&!vvis[find(i)])
    126         {
    127             vvis[find(i)]=1;
    128             qwq++;
    129             if(qwq>1){
    130             flag=2;
    131             break;}
    132         }
    133     }
    134     Topsort();
    135     if(orz2<n)flag=3;
    136 }
    137     if(flag==2)printf("UNCERTAIN
    ");
    138     else if(flag==3)printf("CONFLICT
    ");
    139     else printf("OK
    ");
    140     }
    141 
    142     return 0;
    143 }
  • 相关阅读:
    poj2823单调队列认知
    有关二叉树的三序遍历的题目
    hdu4757 可持续字典树
    ZOJ2532判断边是否是割集中的边
    poj2455 k条路最小化最长边
    乘法逆元模板
    poj1699 KMP+壮压DP
    Innodb存储引擎——非聚集索引
    java集合框架笔记
    jvm垃圾回收
  • 原文地址:https://www.cnblogs.com/MekakuCityActor/p/9013353.html
Copyright © 2011-2022 走看看