POJ:1094-Sorting It All Out(拓扑排序经典题型)

Sorting It All Out

Time Limit: 1000MS Memory Limit: 10000K

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.


解题心得:

  • 题意就是给你一系列的关系,让你从他给出的关系中从小到大排一个序,如果给出的关系中发生冲突,输出发生冲突的那一步,如果可以得到一个序,输出题目给出到第几个关系才能确定顺序。
  • 其实就是给出一个关系,然后拓扑排序判断一下,因为最多只有26个字母,所以怎么写都不会超时。如果题目给出的关系发生冲突,那么必然可以形成环,所以判断环就行,如果能够确定n个点的关系,那么每次只能出现一个出度为0的点,最后n个点的顺序全得到。思路比较简单,只要不手贱写一些BUG那么还是很容易用代码实现的。

#include<stdio.h>
#include<algorithm>
#include<set>
#include<stack>
#include<vector>
#include<cstring>
using namespace std;
const int maxn = 100;
char s[maxn];
vector <int> ve[maxn];//用不定长数组来存储边的关系
int out[maxn],n,m;
bool vis[maxn],maps[maxn][maxn];
int ans;
stack <int> st1;
void init()
{
    ans = -1;
    for(int i=0; i<maxn; i++)
        ve[i].clear();
    memset(out,0,sizeof(out));
    memset(maps,0,sizeof(maps));
    memset(vis,0,sizeof(vis));
}

int toposort(int pos)
{
    maps[s[0]][s[2]] = true;
    vis[s[0]] = vis[s[2]] = true;//已经出现了的点
    out[s[0]]++;//出度++
    ve[s[2]].push_back(s[0]);
    int in1[maxn],out1[maxn];
    bool vis1[maxn];
    memcpy(out1,out,sizeof(out));
    memcpy(vis1,vis,sizeof(vis));
    stack<int>st;
    bool flag = false;
    while(1)
    {
        int num = 0;
        vector<int>va;
        for(int i='A'; i<'A'+n; i++)
        {
            if(out1[i] == 0 && vis1[i])//出度为零并且已经出现了的点
                va.push_back(i);
        }
        if(va.size() > 1)//出度为0的点不止一个做好标记
            flag = true;
        if(va.size() == 0)//没有出度为0的点了
            break;

        for(int i=0; i<va.size(); i++)//根据拓扑排序来解决这个出度为0的点
        {
            int k = va[i];
            st.push(k);
            vis1[k] = false;
            for(int j=0;j<ve[k].size();j++)
                out1[ve[k][j]]--;
        }
    }
    int sum2 = 0;
    for(int i='A'; i<'A'+n; i++)//检查是否出现了环
        if(out1[i])
            sum2++;
    if(sum2 != 0)
    {
        //如果有环记录出现环的步数,然后直接返回
        ans = pos;
        return 2;
    }
    if(flag)//出现了多个入度为零的点
        return 1;
    if(st.size() == n)//找到了n个符合拓扑排序的点
    {
        ans = pos;
        st1 = st;
        return 3;
    }
    return 1;//给出的关系不够不能得出答案
}

int main()
{
    while(scanf("%d%d",&n,&m) && n+m)
    {
        init();//初始化一些数组
        bool cont_flag = false;//是否已经出现结果
        int k;
        for(int i=1; i<=m; i++)
        {
            scanf("%s",s);
            if(cont_flag)
                continue;
            if(maps[s[0]][s[2]])//去除重边
                continue;

            k = toposort(i);
            if(k == 2)
                cont_flag = true;
            if(k == 3)
                cont_flag = true;
        }
        if(k != 3 && k != 2)//没找到答案也未出现环,说明给出的关系不足以判断
            printf("Sorted sequence cannot be determined.\n");
        if(k == 2)
            printf("Inconsistency found after %d relations.\n",ans);
        if(k == 3)
        {
            printf("Sorted sequence determined after %d relations: ",ans);
            while(st1.size())
            {
                printf("%c",st1.top());
                st1.pop();
            }
            printf(".\n");
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值