• NYOJ 349 Sorting It All Out (拓扑排序 )


    题目链接

    描述

    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 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.
    • 输出
      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.
    • 样例输入
      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
    • 样例输出
      Sorted sequence determined after 4 relations: ABCD.
      Inconsistency found after 2 relations.
      Sorted sequence cannot be determined.

    分析:

    首先补充一下拓扑排序的思想:

    (1)从有向图中选择一个没有前驱(入度为0)的顶点并输出它。

    (2)从图中删除该节点,并且删去从该节点出发的全部有向边。

    (3)重复上述操作,知道图中不在存在没有前驱的顶点为止。

    这样操作的结果有两种:一种是图中全部定点被输出,这说明图中不存在有向回路;另一种是图中顶点未被全部输出,剩余的顶点均有前驱节点,这说明图中存在有向回路。

    这就是一个典型的拓扑排序的应用,如果能够排好序的话,说明就是可以的,如果形成环的话,说明能够构成回路也就是存在冲突,否则就是不能够排好序。

    代码:

    #include<stdio.h>
    #include<iostream>
    #include<vector>
    #include<queue>
    #include<string.h>
    using namespace std;
    int du[30];
    char ch[30];
    int n,m,k;
    vector<int> v[30];
    int init()
    {
        memset(du,0,sizeof(du));
        memset(v,0,sizeof(v));
    }
    int topSort()
    {
        int op=1;
        k=0;
        queue<int >q;
        int du1[30];
        for(int i=0; i<n; i++)///要把入度的函数复制一下,不然会影响下次的排序
        {
            du1[i]=du[i];
            if(du1[i]==0)
                q.push(i);
        }
        while(!q.empty())
        {
            //cout<<"  ----"<<q.size()<<endl;
            if(q.size()>1) op=0;///相当于有多个入度为0的点,也就是还没有排好序
            int a=q.front();
            q.pop();
            char c=a+'A';
            ch[k++]=c;
            // cout<<"k="<<k<<endl;
            for(int i=0; i<v[a].size(); i++)
            {
                int b=v[a][i];
                du1[b]--;
                if(du1[b]==0)
                    q.push(b);
            }
        }
        if(k<n)///形成环,如果没有形成环且能排好序的话,肯定每一个点都要入队一次
            return -1;
        return op;///op==1,已经排好序;op=1,还没有排好
    }
    int main()
    {
        char ch2,ch1;
        int a,b;
        while(~scanf("%d%d",&n,&m),n,m)
        {
            init();
            int flag=0;
            for(int mm=1; mm<=m; mm++)
            {
                scanf(" %c<%c",&ch1,&ch2);
                if(flag!=0) continue;///已经确定当前的序列是有序或者已经发生冲突
                a=ch1-'A';
                b=ch2-'A';
                // cout<<a<<"   "<<b<<endl;
                v[a].push_back(b);///单向
                du[b]++;
                flag=topSort();///每次加入一个都要进行一次判断,看能否满足某个条件
                if(flag==1)///已经排好序
                {
                    printf("Sorted sequence determined after %d relations: ",mm);
                    for(int k1=0; k1<k; k1++)
                    {
                        printf("%c",ch[k1]);
                    }
                    printf(".
    ");
                }
                if(flag==-1)///发生冲突
                {
                    printf("Inconsistency found after %d relations.
    ",mm);
                }
            }
            if(flag==0)///到最后还没有排好序
            {
                printf("Sorted sequence cannot be determined.
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    C++编程开发学习的50条建议(转)
    编程思想:我现在是这样编程的(转)
    Linux系统编程@多线程与多进程GDB调试
    字符串分割函数 STRTOK & STRTOK_R (转)
    C语言指针与数组的定义与声明易错分析
    C语言 a和&a的区别
    C语言二重指针与malloc
    【C语言入门】C语言的组成结构(基础完整篇)!
    程序员吐槽女友败家:开酒店必须400元起步,工资却不到自己的一半!
    怎样才能和编程语言对上眼?你需要做些准备以及...
  • 原文地址:https://www.cnblogs.com/cmmdc/p/6780805.html
Copyright © 2020-2023  润新知