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

题意:关于Rating的信息。这些信息可能有三种情况,分别是"A > B","A = B","A < B",分别表示A的Rating高于B,等于B,小于B。根据这些信息是否能够确定出这个高手榜,是的话就输出"OK"。否则就请你判断出错的原因,到底是因为信息不完全(输出"UNCERTAIN"),还是因为这些信息中包含冲突(输出"CONFLICT")。注意,如果信息中同时包含冲突且信息不完全,就输出"CONFLICT"。

思路:拓扑排序  A > B 就在图中画一条A-->B的有向边整体画完后找到入度为0的点他一定是榜单的第一,如果入度为0的点有多个说明榜单不完整,然后将和他有联系的点入度-1,再找入度为0的点知道再也找不到为止,这是判断点是否用完,用完了说明榜单完整,没用完说明有环,有冲突。但是题目中有A = B 这种数据,所以要用到并查集,将相等的点合并为一个集合,然后所有的操作都有父亲节点完成

如 A = B, A > C, C > B;因为A = B 所以并查集合并,A为父亲,A > C 建立有向边,C > B 将B节点的父亲A代替B,C的父亲还是C, 这样C > A 冲突了

操作的都是父亲节点。其他同上

#include<iostream>

#include<cstdio>

#include<stack>

#include<vector>

#include<queue>

using namespace std;



struct node

{

    int father;

}node[10005];

int num[10005];

int sum = 0;

void Make_set(int n)

{

    int i;

    for(i = 0; i < n; i++)

    {

        node[i].father = i;

        num[i] = 0;

    }

}



int Find_set(int x)

{

    if(x != node[x].father)

    {

        node[x].father = Find_set(node[x].father);

    }

    return node[x].father;

}



bool Union(int a,int b)

{

    int x = Find_set(a);

    int y = Find_set(b);



    if(x == y)

        return 0;

    else

    {

        node[y].father = x;

    }

    return 1;

}



void topsort(vector<int> v[],int n)

{

    queue<int> q;

    int i;

    for(i = 0;i < n; i++)

    {

        if(num[i] == 0 && Find_set(i) == i)

            q.push(i);

        

    }



    int flag = 0;

    while(!q.empty())

    {    

        if(q.size() > 1)

        {

            flag = 1;

        }

        int i;

        int t = q.front();

        q.pop();sum--;

        for(i = 0; i < v[t].size(); i++)

        {

            num[v[t][i]]--;

            if(!num[v[t][i]])

                q.push(v[t][i]);

        }

    }

    

    if(sum > 0)

        printf("CONFLICT\n");

    else if(flag)

        printf("UNCERTAIN\n");

    else

        printf("OK\n");

}



int main()

{

    int n,m;

    while(scanf("%d%d",&n,&m) != EOF)

    {

        sum = n;

        Make_set(n);

        vector<int> v[10005];

        int i,a[10005],b[10005];

        char c[10005];

        for(i = 0; i < m; i++)

        {

            scanf("%d %c %d",&a[i],&c[i],&b[i]);

            if(c[i] == '=')

            {

                if(Union(a[i],b[i]))

                    sum--;

            }

        }

        for(i = 0; i < m; i++)

        {

            if(c[i] != '=')

            {

                int x = Find_set(a[i]);

                int y = Find_set(b[i]);

                if(c[i] == '>')

                {

                    v[x].push_back(y);

                    num[y]++;

                }

                else

                {

                    v[y].push_back(x);

                    num[x]++;

                }

            }

        }

        topsort(v,n);

    }

    return 0;

}

 

 

 

你可能感兴趣的:(rank)