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

来源:互联网 发布:小甲鱼零基础学python 编辑:程序博客网 时间:2024/06/03 20:45

代码抄自:hdu1811 - Ice_Crazy的专栏 - 博客频道 - CSDN.NET

题目大意:给你一些大小关系,让你判断是否能够使所有元素有序排列起来。如果可以输出OK,要是有冲突输出CONFLICT,在没有冲突的条件下如果关系不满足全部排序,输出UNCERTAIN。

Eage类中的from代表较大值x,to代表较小值y,next是x的下一个直接下属yi所组成的Eage在ee数组中的编号,next为-1时代表遍历完全所有的yi。

#include <iostream>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <algorithm>#include <queue>using namespace std;const int maxn = 10010;const int maxm = 20010;int n, m;int father[maxn], in[maxn], ans;struct Eage{    int from, to, next;}ee[maxm];int head[maxn], a[maxm], b[maxm], tot;char sh[maxm][4];//x为较大值,y为较小值void add(int x, int y){    ee[tot].from = x;    ee[tot].to = y;    //上一次x作为较大值时所存边的编号    ee[tot].next = head[x];    head[x] = tot++;}int find_father(int k){    if(father[k] == k)        return k;    return father[k] = find_father(father[k]);}int Get_Map(){    int fa, fb;    for(int i = 0; i < n; i++)        father[i] = i;    for(int i = 0; i < m; i++)    {        scanf("%d%s%d", &a[i], sh[i], &b[i]);        //相等合并为一点        if(sh[i][0] == '=')        {            fa = find_father(a[i]);            fb = find_father(b[i]);            father[fb] = fa;        }    }    memset(head, -1, sizeof(head));    memset(in, 0, sizeof(in));    //father数组一步到位    for(int i = 0; i < n; i++)        find_father(i);    tot = 0;    for(int i = 0; i < m; i++)    {        //并点后发现关系发生矛盾,直接输出矛盾        if(father[a[i]] == father[b[i]] && sh[i][0] != '=')            return 1;        if(sh[i][0] == '>')        {            add(father[a[i]], father[b[i]]);            in[father[b[i]]]++;        }        if(sh[i][0] == '<')        {            add(father[b[i]], father[a[i]]);            in[father[a[i]]]++;        }    }    return 0;}int Topsort(){    int flag, tmp, now, tot2;    queue<int> q;    tot = flag = tmp = 0;    for(int i = 0; i < n; i++)    {        if(father[i] == i)        {            tot++;            //入度为0,即rating最大的点,环上的点入度均不为0            if(!in[i])            {                tmp++;                q.push(i);            }            //rating最大的点不止一个,但还是有可能会有矛盾关系            if(tmp > 1)                flag = 2;        }    }    int k = 0, v;    while(!q.empty())    {        now = q.front();        q.pop();        //记录有多少条合法边        k++;        in[now]--;        tmp = 0;        for(int j = head[now]; j != -1; j = ee[j].next)        {            v = ee[j].to;            in[v]--;            if(!in[v])            {                //直接下属不止一个,可能是不能确定,但也有可能剩下的关系会矛盾                tmp++;                //为了检测删点是否有环                q.push(v);            }        }        //删点之后剩余的rating最大点不止一个        if(tmp > 1)            flag = 2;    }    //合法边与总边数不等    if(k < tot)        flag = 1;    return flag;}int main(){//    freopen("1811.in", "r", stdin);    while(~scanf("%d%d", &n, &m))    {        ans = Get_Map();        if(!ans)            ans = Topsort();        if(!ans)            puts("OK");        else if(ans == 1)            puts("CONFLICT");        else            puts("UNCERTAIN");    }    return 0;}



0 0
原创粉丝点击