zoukankan      html  css  js  c++  java
  • HDU 1811 Rank of Tetris(并查集+拓扑排序 非常经典)

    Rank of Tetris

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


    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
     
    Author
    linle
     
    Source
     
    Recommend
    lcy   |   We have carefully selected several similar problems for you:  1558 1879 1863 1875 1823 
     
    分析:
    如果直接拓扑的话,等号的情况很麻烦
    一.采用并查集处理=号的情况
    把具有等号关系的点聚合成为一个连通分量,且只用该连通分量的根结点替代分量中的所有点
    比如A=B=C=D
    以后A,B,C,D这四个点就只用A来表示
     
    需要注意的地方:
    1.必须先处理完所有的等号之后再进行拓扑排序(最后才想到!!!)
    2.因为存在等号,我们有把等号处理了,所有我们可以拓扑的点可能不是n个了,而是根结点的个数个
     
    2.采用拓扑排序处理>和<的情况
     
    ps:
    冲突情况:存在环,也就是进入队列的点不等于可以拓扑的点
    信息不完全:某时刻队列里面元素个数大于1个,说明图不是连通图
     
     
    必须先处理完所有等号的情况才能进行拓扑!!!
    wa好多次
     
    #include<stdio.h>
    #include<iostream>
    #include<math.h>
    #include<string.h>
    #include<set>
    #include<map>
    #include<list>
    #include<queue>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    int mon1[13]= {0,31,28,31,30,31,30,31,31,30,31,30,31};
    int mon2[13]= {0,31,29,31,30,31,30,31,31,30,31,30,31};
    int dir[4][2]= {{0,1},{0,-1},{1,0},{-1,0}};
    
    int getval()
    {
        int ret(0);
        char c;
        while((c=getchar())==' '||c=='
    '||c=='
    ');
        ret=c-'0';
        while((c=getchar())!=' '&&c!='
    '&&c!='
    ')
            ret=ret*10+c-'0';
        return ret;
    }
    
    #define max_v 20005
    int pa[max_v];
    int rk[max_v];
    int indgree[max_v];
    int a[max_v],b[max_v];
    char o[max_v];
    queue<int> q;
    vector<int> vv[max_v];
    int n,m,cnt;
    int fa_num;
    void init()
    {
        for(int i=0; i<=n; i++)
            pa[i]=i,rk[i]=0;
        memset(indgree,0,sizeof(indgree));
        while(!q.empty())
            q.pop();
        for(int i=0; i<=n; i++)
            vv[i].clear();
        fa_num=0;
        cnt=0;
    }
    int find_set(int x)
    {
        if(x!=pa[x])
            pa[x]=find_set(pa[x]);
        return pa[x];
    }
    void union_set(int x,int y)
    {
        x=find_set(x);
        y=find_set(y);
        if(x==y)
            return ;
        if(rk[x]>rk[y])
            pa[y]=x;
        else
        {
            pa[x]=y;
            if(rk[x]==rk[y])
                rk[y]++;
        }
    }
    int tpsort()
    {
        for(int i=1; i<=n; i++)
        {
            if(find_set(i)==i)//拓扑点必须是根结点
            {
                fa_num++;//计数 根结点
                if(indgree[i]==0)
                    q.push(i);
            }
        }
        int temp;
        int flag=0;
        while(!q.empty())
        {
            if(q.size()>1)
                flag=1;//信息不完全
            temp=q.front();
            q.pop();
            cnt++;
    
            for(int i=0; i<vv[temp].size(); i++)
            {
                indgree[find_set(vv[temp][i])]--;
                if(indgree[find_set(vv[temp][i])]==0)
                    q.push(find_set(vv[temp][i]));
            }
        }
        if(flag)//不能全拓扑(整个图不是连通的)
            return 1;
        else
            return 0;
    }
    int main()
    {
        int x,y;
        char c;
        while(~scanf("%d %d",&n,&m))
        {
           if(n==1&&m==0)
            {
                printf("OK
    ");
                continue;
            }
            init();
            int flag1=0;//冲突 1
            int flag2=0;//信息不完全 1
            for(int i=1; i<=m; i++)//必须先合并除去=号,不能边除去边拓扑!!!
            {
                getchar();
                scanf("%d %c %d",&a[i],&c,&b[i]);
                a[i]++,b[i]++;
                o[i]=c;
                if(c=='=')
                {
                    union_set(a[i],b[i]);
                }
            }
            for(int i=1;i<=m;i++)
            {
                if(o[i]=='=')
                    continue;
                x=find_set(a[i]);
                y=find_set(b[i]);
                if(o[i]!='='&&find_set(x)==find_set(y))
                {
                    flag1=1;
                    continue;
                }
                if(o[i]=='<')
                {
                    int temp=x;
                    x=y;
                    y=temp;
                }
                if(count(vv[y].begin(),vv[y].end(),x)!=0)//环的一种情况
                {
                    flag1=1;
                }
                if(count(vv[x].begin(),vv[x].end(),y)==0)//预防重边
                {
                    vv[x].push_back(y);
                    indgree[y]++;
                }
            }
            flag2=tpsort();
            if(cnt!=fa_num)//不能全排列拓扑,因为信息不全
                flag1=1;
            if(flag1==0&&flag2==0)
            {
                printf("OK
    ");
            }
            else if(flag1==1&&flag2==1)
            {
                printf("CONFLICT
    ");
            }
            else if(flag2==1&&flag1==0)
            {
                printf("UNCERTAIN
    ");
            }
            else if(flag1==1&&flag2==0)
            {
                printf("CONFLICT
    ");
            }
        }
        return 0;
    }
     
     
  • 相关阅读:
    MySQL数据库“局部”乱码
    每个人都可以写博客
    命令行导入SQL文件
    数据库连接扩展
    PHP程序设计经典300例
    C# 调用外部dll
    asp.net中实现文件下载功能
    Windows10下Docker的安装
    java基础——面向对象
    java基础——第一章概述
  • 原文地址:https://www.cnblogs.com/yinbiao/p/9845756.html
Copyright © 2011-2022 走看看