• P1347 排序


    题目链接

    题目描述

    一个不同的值的升序排序数列指的是一个从左到右元素依次增大的序列,例如,一个有序的数列A,B,C,D 表示A<B,B<C,C<D。在这道题中,我们将给你一系列形如A<B的关系,并要求你判断是否能够根据这些关系确定这个数列的顺序。

    输入格式

    第一行有两个整数n,m,n表示需要排序的元素数量,2<=n<=26,第1到n个元素将用大写的A,B,C,D....表示。m表示将给出的形如A<B的关系的数量。

    接下来有m行,每行有3个字符,分别为一个大写字母,一个<符号,一个大写字母,表示两个元素之间的关系。

    输出格式

    若根据前x个关系即可确定这n个元素的顺序yyy..y(如ABC),输出

    Sorted sequence determined after xxx relations: yyy...y.

    若根据前x个关系即发现存在矛盾(如A<B,B<C,C<A),输出

    Inconsistency found after 2 relations.

    若根据这m个关系无法确定这n个元素的顺序,输出

    Sorted sequence cannot be determined.

    (提示:确定n个元素的顺序后即可结束程序,可以不用考虑确定顺序之后出现矛盾的情况)

    方法:

    判环:拓排时记录indegree==0的节点数,若小于当时含有的总节点数,则有环。

    判定成功:层数==n。

    Code:

    #include <bits/stdc++.h>
    # define LL long long
    using namespace std;
    
    const int maxn=27;
    int n,m;
    vector<int> adj[maxn];
    int ind[maxn];
    int tmpind[maxn];
    set<int> have;
    int level[maxn];
    bool hascycle;
    bool complete;
    
    void print(){
        queue<int> q;
        int ind1[maxn];
        for(int i=0;i<26;++i){
            ind1[i]=ind[i];
        }
        for(int i=0;i<26;++i){
            if(have.find(i)!=have.end() && ind1[i]==0){
                q.push(i);
                char c='A'+i;
                printf("%c", c);
                break;
            }
        }
    
        while(!q.empty()){
            int u=q.front();
            q.pop();
            for(int i=0;i<adj[u].size();++i){
                int v=adj[u][i];
                --ind1[v];
                if(ind1[v]==0){
                    char c='A'+v;
                    printf("%c", c);
                    q.push(v);
                }
            }
        }
    }
    
    void topo(){
        for(int i=0;i<26;++i){
            tmpind[i]=ind[i];
        }
        memset(level,0,sizeof(level));
        int maxlevel=0;
        int cnt=0;
        queue<int> q;
        for(int i=0;i<26;++i){
            if(have.find(i)!=have.end() && tmpind[i]==0){
                q.push(i);
                cnt++;
                level[i]=1;
            }
        }
    
        while(!q.empty()){
            int u=q.front();
            q.pop();
            for(int i=0;i<adj[u].size();++i){
                int v=adj[u][i];
                --tmpind[v];
                level[v]=max(level[v],1+level[u]);
                maxlevel=max(maxlevel,level[v]);
                if(tmpind[v]==0){
                    cnt++;
                    q.push(v);
                }
            }
        }
    
        if(cnt!=have.size()){
            hascycle=true;
            return;
        }
    
        if(maxlevel==n){
            complete=true;
            return;
        }
    }
    
    int main(){
        scanf("%d %d", &n, &m);
        hascycle=false;
        complete=false;
        for(int i=1;i<=m;++i){
            string s;
            cin>>s;
            int u=s[0]-'A';
            int v=s[2]-'A';
            have.insert(u);
            have.insert(v);
            adj[u].push_back(v);
            ind[v]++;
    
            topo();
    
            if(hascycle){
                printf("Inconsistency found after %d relations.", i);
                return 0;
            }
    
            if(complete){
                printf("Sorted sequence determined after %d relations: ",i);
                print();
                printf(".");
                return 0;
            }
        }
        printf("Sorted sequence cannot be determined.");
        return 0;
    }
  • 相关阅读:
    InstallShield 12 制作安装包
    php常用知识集锦
    Bootstrap是什么
    php实现简单的学生管理系统
    php实现邮箱激活功能
    php定界符<<<EOF讲解
    qq邮箱的SMTP服务器是什么
    mysqli一些常用方法及详解
    mysqli的简单工具包
    mysqli数据库操作简单实例
  • 原文地址:https://www.cnblogs.com/FEIIEF/p/12243137.html
Copyright © 2020-2023  润新知