洛谷 P1347 排序

https://www.luogu.org/problem/show?pid=1347

题目描述

一个不同的值的升序排序数列指的是一个从左到右元素依次增大的序列,例如,一个有序的数列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个元素的顺序后即可结束程序,可以不用考虑确定顺序之后出现矛盾的情况)

输入输出样例

输入样例#1:
1:
4 6
A<B
A<C
B<C
C<D
B<D
A<B

2:
3 2
A<B
B<A

3:
26 1
A<Z
输出样例#1:
1:
Sorted sequence determined after 4 relations: ABCD.
2:
Inconsistency found after 2 relations.
3:
Sorted sequence cannot be determined.

x<y,由x向y连一条有向边
拓扑排序形成的序列长度 != 当前元素个数,出现环,即有矛盾
拓扑排序过程中,删除一个点后,由>1个的点入队,无法判断
拓扑排序形成的序列长度 = 当前元素个数,而且不满足上一条,可以排序
#include<cstdio>
#include<stack>
using namespace std;
bool v[30];
char s[5];
int in[30],out[30][30],tin[30];
int n,m,tot;
int ans[30];
stack<int>st;
int judge()
{
    bool have=false;
    bool cannt=false;
    ans[0]=0;
    for(int i=1;i<=26;i++)  
    {
        tin[i]=in[i];
        if(v[i]&&!in[i])
        {
            st.push(i);
            if(!have) have=true;
            else cannt=true;
            ans[++ans[0]]=i;
        }
    }
    if(st.empty()) return 1;
    int now; 
    int pass=0;
    while(!st.empty())
    {
        now=st.top(); have=false; st.pop();
        for(int i=1;i<=out[now][0];i++)
        {
            tin[out[now][i]]--;
            if(!tin[out[now][i]])
            {
                st.push(out[now][i]);
                if(!have) have=true;
                else cannt=true;
                ans[++ans[0]]=out[now][i];
            }
        }
    }
    if(ans[0]!=tot) return 1;
    if(cannt) return 2;
    return 0;
}
int main()
{
    /*freopen("data.txt","r",stdin);
    freopen("my.txt","w",stdout);*/
    scanf("%d%d",&n,&m);
    int j,k;
    for(int i=1;i<=m;i++)
    {
        scanf("%s",s);
        if(!v[s[0]-'A'+1])  { tot++; v[s[0]-'A'+1]=true; }
        if(!v[s[2]-'A'+1])  { tot++; v[s[2]-'A'+1]=true; }
        j=s[0]-'A'+1; 
        k=s[2]-'A'+1;
        in[k]++;
        out[j][++out[j][0]]=k;
        if(judge()==1) 
        {
            printf("Inconsistency found after %d relations.",i);
            return 0;
        }
        if(tot==n && !judge())
        {
            printf("Sorted sequence determined after %d relations: ",i);
            for(int i=1;i<=n;i++) putchar(ans[i]+'A'-1);
            putchar('.');
            return 0;
        }
    }
    printf("Sorted sequence cannot be determined.");
}
原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/6979991.html