POJ 1094-Sorting It All Out(拓扑排序)

Sorting It All Out
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 37849   Accepted: 13361

Description

An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequence A, B, C, D implies that A < B, B < C and C < D. in this problem, we will give you a set of relations of the form A < B and ask you to determine whether a sorted order has been specified or not.

Input

Input consists of multiple problem instances. Each instance starts with a line containing two positive integers n and m. the first value indicated the number of objects to sort, where 2 <= n <= 26. The objects to be sorted will be the first n characters of the uppercase alphabet. The second value m indicates the number of relations of the form A < B which will be given in this problem instance. Next will be m lines, each containing one such relation consisting of three characters: an uppercase letter, the character "<" and a second uppercase letter. No letter will be outside the range of the first n letters of the alphabet. Values of n = m = 0 indicate end of input.

Output

For each problem instance, output consists of one line. This line should be one of the following three:

Sorted sequence determined after xxx relations: yyy...y.
Sorted sequence cannot be determined.
Inconsistency found after xxx relations.

where xxx is the number of relations processed at the time either a sorted sequence is determined or an inconsistency is found, whichever comes first, and yyy...y is the sorted, ascending sequence.

Sample Input

4 6
A<B
A<C
B<C
C<D
B<D
A<B
3 2
A<B
B<A
26 1
A<Z
0 0

Sample Output

Sorted sequence determined after 4 relations: ABCD.
Inconsistency found after 2 relations.
Sorted sequence cannot be determined.

Source


题目大意:对字母表前n个字母,给出你它们m个关系,在这m个关系中,看看是否能确定它们的严格拓扑序,就是大小关系是唯一的(每一个字母只能有一个排在它们前面或者后面),如果不唯一就输出“Sorted sequence cannot be determined.”,如果前k个关系中发现有环,就输出“Inconsistency found after k relations.”,前k个关系能确定严格的排序关系就输出Sorted sequence determined after k relations: 排列顺序.所以说对于每次输入的关系你都要进行拓扑排序一次。


首先我们来讲一下什么是拓扑序,就是按照关系排序,和现实生活中的祖先后代那样的关系类似, 严格排序就是: 你只能有一个爸爸和儿子没有环就是: 你爸爸不能是你儿子,你爸爸不能是你儿子的儿子这样的关系。

那么我们怎样来求这个关系呢?方法就是: 每次找到入度为0的那个结点加入队列,然后删除它,并且把它所指向的节点的入度减一,在进行此类操作,如果操作数等于总结点数,那么这个关系就是正确的。

那么在这道题中,我们还要求严格排序,所以每次入队的节点数只能是1

AC代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<queue>
#include<map>
#include<set>
#define bug printf("*********\n");
#define mem0(a) memset(a, 0, sizeof(a));
#define mem1(a) memset(a, -1, sizeof(a));
#define in1(a) scanf("%d" ,&a);
#define in2(a, b) scanf("%d%d", &a, &b);
#define out1(a) printf("%d\n", a);
#define out2(a, b) printf("%d %d\n", a, b);
using namespace std;
typedef long long LL;
typedef pair<int, int> par;
const int mod = 1e9+7;
const int INF = 1e9+7;
const int N = 1000010;
const double pi = 3.1415926;

int n, m, cnt, s, flag, ok, idx;
int head[30], d[30], du[30], put[30];
char str[10];

void inti()
{
    mem0(d);
    mem1(head);
    cnt = 0;
    flag = 0;
    s = 0;
    ok = 0;
}

struct edge //我们用邻接表来存关系,也可以用邻接矩阵
{
    int end;
    int next;
}e[10010];

void add(int u, int v)
{
    e[cnt].end = v;
    e[cnt].next = head[u];
    head[u] = cnt ++;
}

int topo()
{
    queue<int> q;
    while(!q.empty()) q.pop();
    memcpy(du, d, sizeof(d)); //更新关系
    //注意下:用这个函数一定要注意空间的大小,否则会修改你其他数组的值
    for(int i = 0; i < n; i ++)  {
        if(du[i] == 0)
            q.push(i);
    }
    s = 0;
    int f = 1;
    while(!q.empty()) {
        if(q.size() > 1) f = 0;
        int cur;
        cur = q.front();
        q.pop();
        put[s ++] = cur;
        for(int i = head[cur]; i != -1; i = e[i].next) {
            int en = e[i].end;
            du[en] --;
            if(du[en] == 0)
                q.push(en);
        }
    }
    if(s != n) return -1;
    return f;
}

int main()
{
    int x, y;
    while(~scanf("%d%d", &n, &m) && n && m) {
        inti();
        for(int i = 0; i < m; i ++) {
            scanf("%s", str);
            x = str[2] - 'A';
            y = str[0] - 'A';
            add(x, y);
            d[y] ++;
            if(flag == 1 || flag == -1) continue;
            //如果已经确定顺序或者发现有环就不用再继续排序了
            flag = topo();
            if(flag == -1) ok = 1;
            idx = i+1; //位置记录
        }
        if(flag == 1) {
            printf("Sorted sequence determined after %d relations: ", idx);
            for(int i = s-1; i >= 0; i --)
                printf("%c", put[i]+'A');
            printf(".\n");
        }else if(ok) printf("Inconsistency found after %d relations.\n", idx);
        else printf("Sorted sequence cannot be determined.\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/i_believe_cwj/article/details/80327550