【洛谷P1347】排序

今天接着开心学(被)习(虐)图论

这道题有点像板子题 我们把拓扑排序的一种思想讲清楚来
下面先看题目:

P1347 排序

题目描述

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

输入格式

第一行有两个正整数 \(n,m\)\(n\) 表示需要排序的元素数量,\(2\leq n\leq 26\),第 \(1\)\(n\) 个元素将用大写的 \(A,B,C,D,\dots\) 表示。\(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 x 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

输出 #1

Sorted sequence determined after 4 relations: ABCD.

输入输出样例 #2

输入 #2

3 2
A<B
B<A

输出 #2

Inconsistency found after 2 relations.

输入输出样例 #3

输入 #3

26 1
A<Z

输出 #3

Sorted sequence cannot be determined.

说明/提示

\(2 \leq n \leq 26,1 \leq m \leq 600\)

解法&&个人感想

首先 对于这种多次输入多次判定的题目 一定要注意什么呢?
当然是清空数组了! 这可是血的教训
然后我们看到这道题显然是用拓扑排序去做
但是!我们在之前讲过的 拓扑排序能判环还不够
我们在这题要完全排序 就要深刻理解完全排序的含义?
完全排序:指我们在上题车站的等级 这个含义中 等级数和字母数相等
如果矛盾 就是有环!
但是!由于本题的奇妙一个个判断特性 我们不能单纯地用cnt!=n来判断环
而是统计每次的字母数量 然后一次次判断
这样才是对的 调死我了(叹气)
下面!最重要的部分,看!代!码!:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n,m,tot;
char x,pd,y;
int head[605],nex[605],ver[605],deg[30];
int cnt,ans,sum;//cnt表示经过拓扑排序的点数 ans表示等级 sum表示现在有出现字母的个数
int zx[605],zy[605];
int dg[605],dge[605];//dge是永久存放,dg是暂时存放
int a[605];
int vis[605];
struct node{
    int d,rank;
};
void add(int x,int y){
    ver[++tot]=y;
    nex[tot]=head[x];
    head[x]=tot;
}
int toposort(){
    cnt=0,ans=1;
    memset(a,0,sizeof(a));
    queue<node>q;
    for(int i=1;i<=n;i++){
        if(!dg[i]&&vis[i]){
            q.push(node{i,1});
            cnt++;
            a[cnt]=i;
        }
    }
    while(!q.empty()){
        node x=q.front();q.pop();
        for(int i=head[x.d];i;i=nex[i]){
            int y=ver[i];
            dg[y]--;
            if(!dg[y]){
                cnt++;
                ans=max(ans,x.rank+1);
                q.push(node{y,x.rank+1});
                a[cnt]=y;
            }
        }
    }
    if(cnt!=sum) return -1;
    else if(ans!=sum||sum<n) return 0;
    else return 1;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        cin>>x>>pd>>y;
        zx[i]=x-'A'+1,zy[i]=y-'A'+1;
    }
    for(int i=1;i<=m;i++){
        add(zx[i],zy[i]);
        if(!vis[zx[i]]) sum++;
        if(!vis[zy[i]]) sum++;
        vis[zx[i]]=1;vis[zy[i]]=1;
        dge[zy[i]]++;
        for(int j=1;j<=26;j++) dg[j]=dge[j];
        int flag=0;
        flag=toposort();
        if(flag==1){
            cout<<"Sorted sequence determined after "<<i<<" relations: ";
            for(int j=1;j<=n;j++) cout<<(char)('A'-1+a[j]);
            cout<<'.';
            system("pause");
            return 0;
        }
        else if(flag==-1){
            cout<<"Inconsistency found after "<<i<<" relations.";
            system("pause");
            return 0;
        }
        else if(flag==0&&i!=m) continue;
        else if(flag==0&&i==m){
            cout<<"Sorted sequence cannot be determined.";
            system("pause");
            return 0;
        }
    }
    system("pause");
    return 0;
}
posted @ 2025-02-18 23:03  elainafan  阅读(60)  评论(0)    收藏  举报