poj1094

题意:有一些未知数各不相等,给出一些两两比较的大小关系,问到第几个关系开始可以确定整体排序或出现矛盾,再或者所有关系都用过了也无法确定整体排序。

分析:闭包传递,我们每获得一个比较关系就更新我们已知的关系库,关系库中要记录所有我们现在已知的能比较大小的关系对。一条大小关系a<b的信息可以给我们提供如下信息:

1.a<b

2.所有小于a的未知数都小于b

3.所有大于b的未知数都大于a

4.所有大于b的未知数都大于所有小于a的未知数

利用以上四条信息我们可以获得更多的两两大小关系。判断是否已确定整体排序的方法是,判断我们当前的关系库中是否所有对的大小都已知(因为我们能推断出的关系都在关系库中,如果关系库中没有某对的关系则必然是无法判断导致的)。判断是否出现矛盾的方法是,当我们看到a<b这条输入时,是否关系库中已经有了b<a(我们所有能推断出的东西都在关系库里,与关系库不矛盾则与已知不矛盾)。

View Code
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;

#define maxn 30

int n, m;
bool smaller[maxn][maxn];
enum Result
{
    inconsistent, determined, undetermined
};

bool cmp(int a, int b)
{
    return smaller[a][b];
}

int get_id(char a)
{
    return a - 'A';
}

Result work(int a, int b)
{
    if (smaller[b][a])
        return inconsistent;
    smaller[a][b] = true;
    for (int i = 0; i < n; i++)
        if (smaller[i][a])
            smaller[i][b] = true;
    for (int i = 0; i < n; i++)
            if (smaller[b][i])
                smaller[a][i] = true;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            if (smaller[i][a] && smaller[b][j])
                smaller[i][j] = true;
    for (int i = 0; i < n; i++)
        for (int j = i + 1; j < n; j++)
            if (!(smaller[i][j] || smaller[j][i]))
                return undetermined;
    return determined;
}

void input(int x)
{
    char st[5];
    for (int i = x + 1; i < m; i++)
        gets(st);
}

void output()
{
    int f[maxn];
    for (int i = 0; i < n; i++)
        f[i] = i;
    sort(f, f + n, cmp);
    for (int i = 0; i < n; i++)
        putchar(f[i] + 'A');
}

int main()
{
    //freopen("t.txt", "r", stdin);
    while (scanf("%d%d", &n, &m), n | m)
    {
        getchar();
        memset(smaller, 0, sizeof(smaller));
        Result ans = undetermined;
        for (int i = 0; i < m; i++)
        {
            char a, b, opr;
            a = getchar();
            opr = getchar();
            b = getchar();
            getchar();
            if (opr == '<')
                ans = work(get_id(a), get_id(b));
            else
                ans = work(get_id(b), get_id(a));
            if (ans == inconsistent)
            {
                printf("Inconsistency found after %d relations.\n", i + 1);
                input(i);
                break;
            }
            if (ans == determined)
            {
                printf("Sorted sequence determined after %d relations: ", i + 1);
                input(i);
                output();
                printf(".\n");
                break;
            }
        }
        if (ans == undetermined)
            puts("Sorted sequence cannot be determined.");
    }
    return 0;
}

 

posted @ 2013-01-08 15:50  金海峰  阅读(1154)  评论(0编辑  收藏  举报