您的位置:首页 > 其它

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

2016-08-12 18:49 344 查看
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.


这题是一个拓扑排序的经典题。这题的大意是给你一些大写字母的大小关系,让你判断是否能组成拓扑序列。

如果能组成,输出在第几个关系给出后得到的,并输出拓扑序;

如果有环,证明得不到拓扑序,输出在第几个关系给出后出现矛盾的;

如果所有关系都给出了,也判断排不出拓扑序,输出不能确定。

这题有个坑点就是有可能前面的输入就能组成拓扑序列,然后后面的输入有可能和前面矛盾,所以要读入一个关系判断一次拓扑序,如果构成了拓扑序列,后面就光读入,不用处理了。还有一个坑点就是,如果判断了他拓扑序不唯一后,还要再判断他是否有环。

拓扑排序的方法:

1、找到一个入度为0的点,加入队列;

2、取出队列里的一个值,把它连的点的入度都减1,如果被减过有入度为0的点,也把它加入队列;

3、重复上面步骤,直到所有的点都被处理过;

如果最后有点没有被处理,那么肯定有环;

如果队列里有两个及以上的点,拓扑序就不唯一;

一般拓扑排序的时候需要注意判断一下重边,不然结果会出错

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

int a[30][30],in[30],que[30],n;
int toposort()
{
    int i,j,m;
    int temp[30],b[30];
    queue<int> q;
    memset(b,0,sizeof(b));
    for(i=0;i<n;i++)
    {
        temp[i] = in[i];
        if(temp[i] == 0)
        {
            q.push(i);
            b[i] = 1;
        }
    }
    int c = 0;
    int flag = 1;
    while(!q.empty())
    {
        int t = q.front();
        q.pop();
        if(q.size())//有多个入度为0的点,证明拓扑序不唯一
            flag = -1;
        que[c++] = t;
        for(i=0;i<n;i++)
            if(a[t][i] == 1)
            {
                temp[i]--;
                if(temp[i] == 0)
                {
                    q.push(i);
                    b[i] = 1;
                }
            }
    }
    for(i=0;i<n;i++)//有没处理到的点,证明有环
        if(!b[i])
            flag = 0;
    return flag;//能拓扑排序
}

int main(void)
{
    int m,i,j;
    char s[10];
    while(scanf("%d%d",&n,&m)==2)
    {
        if(!n&&!m)
            break;
        memset(a,0,sizeof(a));
        memset(in,0,sizeof(in));
        int flag = 0;
        for(i=1;i<=m;i++)
        {
            scanf("%s",s);
            if(flag)
                continue;
            int x = s[0]-'A';
            int y = s[2]-'A';
            if(s[1] == '<')
            {
                if(!a[x][y])//判断重边
                {
                    a[x][y] = 1;
                    in[y]++;
                }
            }
            if(s[1] == '>')
            {
                if(!a[y][x])//判断重边
                {
                    a[y][x]=1;
                    in[x]++;
                }
            }
            int t = toposort();
            if(t == 0)
            {
                printf("Inconsistency found after %d relations.\n",i);
                flag = 1;
            }
            if(t == 1)
            {
                printf("Sorted sequence determined after %d relations: ",i);
                for(int j=0;j<n;j++)
                    printf("%c",que[j]+'A');
                printf(".\n");
                flag = 1;
            }
        }
        if(!flag)
            printf("Sorted sequence cannot be determined.\n");
    }

    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: