zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    JavaScript cookie详解
    Javascript数组的排序:sort()方法和reverse()方法
    javascript中write( ) 和 writeln( )的区别
    div做表格
    JS 盒模型 scrollLeft, scrollWidth, clientWidth, offsetWidth 详解
    Job for phpfpm.service failed because the control process exited with error code. See "systemctl status phpfpm.service" and "journalctl xe" for details.
    orm查询存在价格为空问题
    利用救援模式破解系统密码
    SSH服务拒绝了密码
    C# 调用 C++ DLL 中的委托,引发“对XXX::Invoke类型的已垃圾回收委托进行了回调”错误的解决办法
  • 原文地址:https://www.cnblogs.com/FEIIEF/p/12243137.html
Copyright © 2011-2022 走看看