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个元素的顺序后即可结束程序,可以不用考虑确定顺序之后出现矛盾的情况)

输入输出样例

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

代码

明显的拓扑序,考虑拓扑排序

考虑三种情况

1.若根据前x个关系即可确定这n个元素的顺序:

拓扑排序刚好分为n

2.若根据前x个关系即发现存在矛盾:

即成环的情况,也就是不存在拓扑序,即不能遍历所有点

3.若根据这m个关系无法确定这n个元素的顺序:

非1,2两种情况

然后对每一次加边都跑一边

#include<bits/stdc++.h>
using namespace std;
const int maxn=200+5;
int head[maxn],in[maxn],tp[maxn];
int t[maxn];
int dep[maxn],vis[maxn];
int tot,cnt;
int n,m;
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x*f; 
}
struct edge
{
    int to,next;
}e[maxn];
int size=0;
void addedge(int u,int v)
{
    e[++size].to=v;e[size].next=head[u];head[u]=size;
}
void init()
{
    memcpy(tp,in,sizeof(tp));
    memset(dep,0,sizeof(dep));
    memset(vis,0,sizeof(vis));
    cnt=0;
}
void topo()
{
    queue<int>q;
    for(int i=0;i<=25;i++)
    if(t[i]&&!in[i])q.push(i),dep[i]=1,vis[++cnt]=i;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int i=head[u];i;i=e[i].next)
        {
            int to=e[i].to;
            if(!tp[to])continue;
            tp[to]--;
            if(!tp[to])dep[to]=dep[u]+1,q.push(to),vis[++cnt]=to;
        } 
    }
}
void print()
{
    char op;
    for(int i=1;i<=cnt;i++)
    op=vis[i]+'A',cout<<op;
    printf(".");
    exit(0);
}
void check(int x)
{
    int d=0;
    for(int i=0;i<=25;i++)
    {
    if(!t[i])continue;
    if(tp[i])printf("Inconsistency found after %d relations.",x),exit(0);
    d=max(d,dep[i]); 
    }
    if(d==n)printf("Sorted sequence determined after %d relations: ",x),print(),exit(0);
}

int main()
{
    n=read();m=read();
    for(int i=1;i<=m;i++)
    {
        char a,b,op;
        cin>>a>>op>>b;
        int u=a-'A',v=b-'A';
        if(op=='<')addedge(u,v),in[v]++;
        else addedge(v,u),in[u]++;
        t[u]=1;t[v]=1;
        init();
        topo();
        check(i);
    }
    printf("Sorted sequence cannot be determined.");
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/DriverBen/p/11005846.html