1811 Rank of Tetris

【原题】

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

【类型】

并查集+拓扑排序

【题意】

给定一些点对之间的关系(大于小于相等),判断是否发生冲突。

【分析】

对于冲突判断,直观的想法就是拓扑排序。以大于号或者小于号方向作为拓扑序的方向,如果处理时出现违反拓扑序列的情况则可判断为冲突。

然后这道题还有另外一个问题就是相等情况的处理,如果直接按照拓扑排序对其进行分析,则可能发生错误。为了解决这个问题,可以用并查集进行预处理,将所有相等的点缩成1个点,然后进行后序的拓扑排序。

#include<iostream>
#include<cstdio>
#include<algorithm>

using namespace std;

int father[10001]; 

void clean_father(int n)
{
    for (int i=0;i<n;i++) father[i]=i;
} 

int getfather(int x)
{
    if (father[x]!=x) father[x]=getfather(father[x]);
    return father[x];
}

void link(int x,int y)
{
    father[getfather(x)]=getfather(y);
} 

int x[20001],y[20001],rd[10001],num[10001],start[10001];
char z[20001];

typedef struct {
    int a,b;
} node;
node a[20001];

bool op(node a,node b)
{
    return a.a<b.a;
}

int stack[10001];

int main()
{
    int n,m;
    while (scanf("%d%d",&n,&m)!=EOF)
    {
        clean_father(n);

        for (int i=1;i<=m;i++)
        {
            scanf("%d %c %d",&x[i],&z[i],&y[i]);
            if (z[i]==‘=‘) link(x[i],y[i]);
        }

        int tail=0;
        for (int i=0;i<n;i++) rd[i]=-1;
        int tot=0;
        for (int i=0;i<n;i++)
        {
            rd[getfather(i)]=0;
            if (rd[i]==0) tot++;
        }
        for (int i=1;i<=m;i++)
        switch(z[i])
        {
            case ‘>‘:
                tail++;
                a[tail].a=getfather(x[i]);
                a[tail].b=getfather(y[i]);
                rd[getfather(y[i])]++;
                break;
            case ‘<‘:
                tail++;
                a[tail].a=getfather(y[i]);
                a[tail].b=getfather(x[i]);
                rd[getfather(x[i])]++;
        }
        sort(&a[1],&a[tail+1],op);

        int o=-1;
        for (int i=0;i<n;i++) num[i]=0;
        for (int i=1;i<=tail;i++)
        {
            if (a[i].a!=o)
            {
                o=a[i].a;
                start[o]=i;
            }
            num[o]++;
        }

        int top=0;
        for (int i=0;i<n;i++)
        if (rd[i]==0)
        {
            top++;
            stack[top]=i;
        }

        if (top==0)
        {
            printf("CONFLICT\n");
            continue;
        }

        bool flag=false,done=false;
        while (top>0&&(!done))
        {
            if (top>1) flag=true;
            int now=stack[top];
            top--;tot--;
            for (int i=0;i<num[now];i++)
            {
                rd[a[start[now]+i].b]--;
                if (rd[a[start[now]+i].b]==0)
                {
                    top++;
                    stack[top]=a[start[now]+i].b;
                } else
                if (rd[a[start[now]+i].b]<0)
                {
                    done=true;
                    break;
                }
            }
            num[now]=0;
        }
        if (tot>0||done) printf("CONFLICT\n");
        else if (flag) printf("UNCERTAIN\n");
        else printf("OK\n");
    }

    return 0;
}

时间: 2024-10-10 20:09:24

1811 Rank of Tetris的相关文章

【HDOJ】1811 Rank of Tetris

并查集+拓扑排序.使用并查集解决a = b的情况. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 7 #define MAXN 10005 8 9 typedef struct ArcNode { 10 int adjvex; 11 ArcNode *next; 12 } ArcNode; 1

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): 4931 Accepted Submission(s): 1359 Problem Description自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想了一个新点子:他

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): 9267    Accepted Submission(s): 2668 Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想

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): 5672    Accepted Submission(s): 1616 Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想

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

Rank of Tetris Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想了一个新点子:他将制作一个全球Tetris高手排行榜,定时更新,名堂要比福布斯富豪榜还响.关于如何排名,这个不用说都知道是根据Rating从高到低

hdoj 1811 Rank of Tetris 【拓扑】+【并查集】

Rank of Tetris Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5428    Accepted Submission(s): 1520 Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想

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): 5415    Accepted Submission(s): 1514 Problem Description 自从Lele开发了Rating系统,他的Tetris事业更是如虎添翼,不久他遍把这个游戏推向了全球. 为了更好的符合那些爱好者的喜好,Lele又想了

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

1 #include "cstdio" 2 #include "iostream" 3 #include "cstring" 4 #include "vector" 5 #include "queue" 6 using namespace std; 7 const int N = 10005; 8 int n, m, t; 9 int fa[N]; 10 int rank[N]; 11 int X[2*N]

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

链接 :  http://acm.hdu.edu.cn/showproblem.php?pid=1811 题目为中文. 可以考虑把rating相同的人放到一个集合里 集合里的人可以认为按照编号排序的,可以使用并查集. 预处理了之后可以考虑在同一个集合里不会出现两个不同的rating 出现即为矛盾 否则可以 以两个集合的根节点建边. 图建好了之后可以保证每个点里面的人的rating相同.只需要再判断是否有环 . 拓扑序是否唯一. 判断拓扑序唯一就是每次队列中只能存在一个集合,否则就是可以有多种