luogu 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:

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.

topo排序

#include <cstdio>
#include <iostream>
#include <queue>
using namespace std;
const int N = 36;
queue<int>que;
int n,m;
bool vis[N];
struct node{
    int v,next;
}edge[N*N/2];
int many=0;
int rd[N],rdd[N];int head[N];int num;
void Add_edge(int x,int y)
{
    edge[++num].v=y;edge[num].next=head[x];head[x]=num;
}
int cnt;
int can[N];
int topsort()
{
    cnt=0;int num=0;
    for(int i=1;i<=26;i++)
    {
        rdd[i]=rd[i];
        if(rdd[i]==0&&vis[i])num++,que.push(i),can[++cnt]=i;
    }
    if(!num)return 1;
    bool a=0;
    while(!que.empty())
    {
        int u=que.front();
        que.pop();int aa=0;
        for(int i=head[u];i;i=edge[i].next)
        {
            int v=edge[i].v;
            rdd[v]--;
            if(rdd[v]==0)
            {
                can[++cnt]=v;
                aa++;
                if(aa>=2)a=1;
                que.push(v);
            }
        }
    }
    if(cnt!=many)return 1;
    if(num>1||a)return 2;
    return 0;
}
int main()
{
    scanf("%d%d",&n,&m);
    char a[10];
    for(int i=1;i<=m;i++)
    {
        scanf("%s",a);
        int tmp=a[0]-‘A‘+1;
        int ttmp=a[2]-‘A‘+1;
        rd[ttmp]++;
        if(!vis[tmp])many++;if(!vis[ttmp])many++;
        vis[tmp]=1; vis[ttmp]=1;
        Add_edge(tmp,ttmp);
        if(topsort()==1)
        {
            printf("Inconsistency found after %d relations.",i);return 0;
        }
        if(!topsort()&&cnt==n)
        {
            printf("Sorted sequence determined after %d relations:",i);
            for(int j=1;j<=cnt;j++)
            {
                putchar(can[i]+‘A‘-1);
            }
            //if(can)
            printf(".");
            return 0;
        }
    }
    puts("Sorted sequence cannot be determined.");
    return 0;
}
时间: 2024-10-21 00:48:16

luogu P1347 排序的相关文章

P1347 排序

codevs—— 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的关系的数量. 接下来有

洛谷 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

P1347 排序(拓扑排序)

这个题是我照着题解一点点理解一点点打出来的. 拓扑排序: 定义:将有向图中的顶点以线性方式进行排序.即对于任何连接自顶点u到顶点v的有向边uv,在最后的排序结果中,顶点u总是在顶点v的前面. 确定一个图的拓扑排序是基于bfs的,bfs是基于队列的. 首先记录所有的点和所有点的入度(在连边时顺便求得的入度), if(vis[aa]!=1) vis[aa]=1,tot++;//tot记录的是目前能算得上点(因为是随读随做) if(vis[cc]!=1) vis[cc]=1,tot++; son[aa

【luogu P2824排序】题解

[HEOI2016/TJOI]排序 题目描述 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这个全排列序列进行m次局部排序,排序分为两种:1:(0,l,r)表示将区间[l,r]的数字升序排序2:(1,l,r)表示将区间[l,r]的数字降序排序最后询问第q位置上的数字. 输入格式 输入数据的第一行为两个整数n和m.n表示序列的长度,m表示局部排序的次数.第二行为n个整数,表

拓扑相关题目

有关拓扑一个挺直观的图: 1.luogu P1347 排序 直通 思路: 题目中明确的提到:确定n个元素的顺序后即可结束程序,可以不用考虑确定顺序之后出现矛盾的情况. 所以我们可以每读入一个条件,就进行一遍Floyd,判断顺序的条件就是: 枚举i,然后用map数组记录一下比i要大的个数,如果n-sum==s+1(s+1的原因是因为我们是从0开始计数的),那么就用一个q数组记录下来 而如果在给出的n之内,只要有一个没有被确定,我们就不能够说已经排好序了 还有一点需要注意的是: · 如果出现了map

luogu P3809 【模板】后缀排序

二次联通门 : luogu P3809 [模板]后缀排序 /* luogu P3809 [模板]后缀排序 后缀数组 sa表示 排名为i的是第几个后缀 求出sa数组后输出即可 */ #include <cstdio> #include <cstring> #define Max 1000008 void read (int &now) { register char word = getchar (); for (now = 0; word < '0' || word

NOIP 车站分级 (luogu 1983 &amp; codevs 3294 &amp; vijos 1851) - 拓扑排序 - bitset

描述 一条单向的铁路线上,依次有编号为 1, 2, ..., n 的 n 个火车站.每个火车站都有一个级别,最低为 1 级.现有若干趟车次在这条线路上行驶,每一趟都满足如下要求:如果这趟车次停靠了火车站 x,则始发站.终点站之间所有级别大于等于火车站 x 的都必须停靠.(注意:起始站和终点站自然也算作事先已知需要停靠的站点)例如,下表是 5 趟车次的运行情况.其中,前 4 趟车次均满足要求,而第 5 趟车次由于停靠了 3 号火车站(2 级)却未停靠途经的 6 号火车站(亦为 2 级)而不满足要求

[Luogu P3953] 逛公园 (最短路+拓扑排序+DP)

题面 传送门:https://www.luogu.org/problemnew/show/P3953 Solution 这是一道神题 首先,我们不妨想一下K=0,即求最短路方案数的部分分. 我们很容易可以想到一个做法,就是魔改迪杰斯特拉做法: 如果一个点可以更新到达其他点的距离,那个点的方案数就是这个点的方案数:如果一个点所更新出来的距离和之前的相等,那个点的方案数加等当前点的方案数. 用式子可以表现为: f[j]=f[i] (dis[j]>dis[i]+x)   f[j]+=f[i] (dis

Luogu 1583 - 魔法照片 - [简单排序题]

题目链接:https://www.luogu.org/problemnew/show/P1583 题目描述一共有n(n≤20000)个人(以1--n编号)向佳佳要照片,而佳佳只能把照片给其中的k个人.佳佳按照与他们的关系好坏的程度给每个人赋予了一个初始权值W[i].然后将初始权值从大到小进行排序,每人就有了一个序号D[i](取值同样是1--n).按照这个序号对10取模的值将这些人分为10类.也就是说定义每个人的类别序号C[i]的值为(D[i]-1) mod 10 +1,显然类别序号的取值为1--