HDU 1881

思路:一开始以为rating相同的点就直接比较rp然后建图,后来想想不对,因为这样发现不了冲突。后来一想对于rating相同的点可以不用排序,因为对于这些点,他们的rp必然不相同,也就是说在这些点的内部必然存在唯一的且合理的排序,因此只需将要将这些点合并成一个点即可,需要用到并查集的知识。

把所有点按上述方法处理后就会得到一些点(暂且称为“有效点”),对于这些有效点再进行拓扑排序即可。

冲突情形:到最后存在环,或者出现a > b,b > c 且 c >a;

不确定情形:同一层中不止一个点入度为0;

确定情形:除以上两种情形;


#include<stdio.h>
#include<string.h>
typedef struct
{
    int to;
    int next;
}EdgeNode;
int cnt;
char str[6];
EdgeNode Edge[20005];
int father[10005],depth[10005];
int L[10005],M[10005],R[10005];
int head[10005],indegree[10005];
int vis[10005],node[10005],temp[10005];
void init(int n)
{
    int i;
    cnt = 0;
    memset(vis,0,sizeof(vis));
    memset(head,-1,sizeof(head));
    memset(indegree,0,sizeof(indegree));
    for(i = 0;i < n;i ++)
    {
        father[i] = i;
        depth[i] = 0;
    }
}

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

void uint(int x,int y)
{
    x = find(x);
    y = find(y);
    if(x == y)
        return ;
    if(depth[x] < depth[y])
        father[x] = y;
    else
    {
        if(depth[x] > depth[y])
            father[y] = x;
        else
        {
            father[x] = y;
            depth[y]++;
        }
    }
    return ;
}

void add_edge(int n,int m)
{
    Edge[cnt].to = m;
    Edge[cnt].next = head[n];
    head[n] = cnt++;
}

int main(void)
{
    int a,b,n,m,i,j,k;
    int sum,flag_U,flag_C;
    while(~scanf("%d %d",&n,&m))
    {
        init(n);
        flag_U = flag_C = 0;
        for(i = 1;i <= m;i ++)
        {
            scanf("%d %c %d",&L[i],&M[i],&R[i]);
            if(M[i] == '=')
            {
                uint(L[i],R[i]);
            }
        }
        for(i = 1;i <= m;i ++)
        {
            if(M[i] == '=')
                continue ;
            a = find(L[i]);
            b = find(R[i]);
            if(a == b)
            {
                flag_C = 1;
                break ;
            }
            else
            {
                if(M[i] == '>')
                {
                    add_edge(b+1,a+1);
                    indegree[a+1]++;
                }
                else
                {
                    add_edge(a+1,b+1);
                    indegree[b+1]++;
                }
            }
        }
        for(i = 1;i <= n;i ++)
        {
            sum = 0;
            for(j = 1;j <= n;j ++)
            {
                if(indegree[j] == 0 && vis[j] == 0 && father[j-1] == j-1)
                    temp[sum++] = j;
            }
            if(sum > 1)
                flag_U = 1;
            for(j = 0;j < sum;j ++)
            {
                vis[temp[j]] = 1;
                for(k = head[temp[j]];k != -1;k = Edge[k].next)
                {
                    if(!vis[Edge[k].to])
                        indegree[Edge[k].to]--;
                }
            }
        }
        for(i = 1;i <= n;i ++)
        {
            if(indegree[i] && father[i-1] == i-1)
            {
                flag_C = 1;
                break ;
            }
        }
        if(!(flag_C+flag_U))
            printf("OK
");
        if(flag_C)
            printf("CONFLICT
");
        if(flag_U && !flag_C)
            printf("UNCERTAIN
");
    }
    return 0;
}



原文地址:https://www.cnblogs.com/anhuizhiye/p/3933260.html