POJ 1094 Sorting It All Out

Sorting It All Out
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 30361 Accepted: 10521

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.

这个题就是个拓扑排序题,因为要输出能够确定最终结果的不等式的序号,所以每输入一个不等式,就要进行一次拓扑排序,并记录结果,直接贴出代码(主要解释在注释里面):

#include <iostream>
#include <algorithm>
#include <iterator>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cctype>
#include <vector>
#include <queue>
using namespace std;

int n;
int indegree[30],tem[30];//indegree记录每个点的入度,tem用于每次记录每次点的入度
char s[5],res[30];//s用于输入操作,res表示如果有解,记录最终的解
bool vis[30];//用来表示第几个元素出现了没
vector<int> v[30];//用于记录图的信息

int toposort(int s)
{
    int i,j,t,cnt,r;//r记录res数组的元素个数,cnt记录入度为0的元素的个数
    bool flag;

    for(int i=0;i<n;i++)
        tem[i]=indegree[i];//每次赋值当前的点的入度
    r=0; flag=1;
    while(s--)//只需要进行s次循环就可以把当前的点全部输入到拓扑排序的res数组中
    {
        cnt=0;
        for(i=0;i<n;i++)
        {
            if(tem[i]==0)
            {
                j=i;cnt++;//cnt记录入度为0的元素的个数,j记录入度为0的下坐标
            }
        }

        if(cnt>=1)
        {
            if(cnt>1)  flag=0;//如果入度为0的元素个数>1,说明不能确定,但是不能直接返回,因为有可能还出现环

            for(i=0;i<v[j].size();i++)
                tem[v[j][i]]--;//更新每个点的入度

            res[r++]='A'+j;
            res[r]=0;
            tem[j]=-1;
        }else if(cnt==0)
        {
            return -1;
        }
    }
    if(flag)
        return r;
    else
        return 0;
}

int main()
{
//    freopen("s","r",stdin);

    int m,dete,c,k;//c记录当前元素的个数,k记录到第几个关系式出现结果,dete用于判断是哪种结果
    while(scanf("%d%d",&n,&m)!=EOF)//n记录总元素的个数,m表示操作数
    {
        if(!n&&!m)  break;

        memset(vis,0,sizeof(vis));
        memset(indegree,0,sizeof(indegree));

        for(int i=0;i<30;i++)
            v[i].clear();
        dete=0; c=0;
        for(int i=0;i<m;i++)
        {

            scanf("%s",s);
            indegree[s[2]-'A']++;
            v[s[0]-'A'].push_back(s[2]-'A');//构建图
            //记录每个点是否存在
            if(!vis[s[0]-'A'])
            {
                c++;
                vis[s[0]-'A']=1;
            }
            if(!vis[s[2]-'A'])
            {
                c++;
                vis[s[2]-'A']=1;
            }

            if(dete==0)
            {
                int t=toposort(c);

                if(t==-1)
                {
                    dete=-1; k=i+1;
                }
                if(t==n)
                {
                    dete=1; k=i+1;
                }
            }
        }

        if(dete==-1)
            printf("Inconsistency found after %d relations.\n",k);
        else if(dete==0)
            printf("Sorted sequence cannot be determined.\n");
        else
            printf("Sorted sequence determined after %d relations: %s.\n",k,res);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值