cqyz oj | 罕见的秩序 | 拓扑排序

Description

  一个珍稀书籍的收藏家最近发现了一本用陌生的语言写的一本书,这种语言采用和英语一样的字母。这本书有简单的索引,但在索引中的条目的次序不同于根据英语字母表给出的字典排序的次序。这位收藏家试图通过索引来确定这个古怪的字母表的字符的次序,(即对索引条目组成的序列进行整理),但因为任务冗长而乏味,就放弃了。
  请编写程序完成这位收藏家的任务,程序输入一个按特定的序列排序的字符串集合,确定字符的序列是什么。

Input

  输入是由大写字母组成的字符串的有序列表,每行一个字符串。每个字符串最多包含20个字符。该列表的结束标志是一个单一字符’#’的一行。并不是所有的字母都被用到,但该列表蕴涵对于被采用的那些字母存在着一个完全的次序。

Output

  输出可能存在三种情况:如果不能得到一个完全次序,则输出none;如果次序不唯一,则输出 non-unique;如果能唯一确定,则输出字母的排列次序。

Sample Input 1

XWYZXZXYZXWYWWX#

Sample Output 1

XZYW

Hint

字符串数目最多不超过5000个。


建图时只需要比较相邻的两个字串来获得字母大小关系,因为两两相互比较的大小关系可以用相邻比较的结果来得到

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
typedef long long ll;
using namespace std;
const int maxn = 30, maxm = 5005, inf = 0x3f3f3f3f;

int fir[maxn], to[maxm], ne[maxm], np;
void add(int x, int y) {
    ne[++np] = fir[x];
    fir[x] = np;
    to[np] = y;
}

char w[maxm][maxn];
int cnt;
void data_in() {
    char tmp[maxn];
    cnt = 0;
    while(true) {
        scanf("%s", tmp);
        if(tmp[0] == ‘#‘) break;
        strcpy(w[++cnt], tmp);
    }
}

int n;
int rd[maxn];
int mark[maxn], ha[maxn][maxn];
vector<int> topo;
int toposort() {
    int ret = 1;
    queue<int> Q;
    for(int i=0; i<26; i++)
        if(mark[i] && !rd[i]) Q.push(i);
    while(!Q.empty()) {
        if(Q.size()>=2) ret = 2;
        int u = Q.front(); Q.pop();
        topo.push_back(u);
        for(int i=fir[u]; i; i=ne[i]) {
            int v = to[i];
            if(!--rd[v]) Q.push(v);
        }
    }
    if(topo.size() < n) ret = 0;
    return ret;
}

void sett() {
    for(int i=2; i<=cnt; i++) {
        int j = i-1, k = 0;
        while(w[i][k] && w[j][k]) {
            if(w[i][k] != w[j][k]) break;
            k++;
        }

        if(w[i][k] && w[j][k]){
            int x = w[i][k] - ‘A‘, y = w[j][k] - ‘A‘;
            if(ha[x][y]) continue;
            ha[x][y] = 1;
            add(x, y); rd[y]++;
            mark[x]++; mark[y]++;
        }
    }

    n = 0;
    for(int i=0; i<26; i++)
        if(mark[i]) n++;
}

void solve() {
    sett();
    int ok = toposort();
    if(ok == 0) puts("none");
    else if(ok == 2) puts("non-unique");
    else
        for(int i = topo.size()-1; i>=0; i--)
            putchar(topo[i]+‘A‘);
}

int main() {
    data_in();
    solve();
    return 0;
}
/*
XWY
ZX
ZXY
ZXW
YWWX
#

*/

原文地址:https://www.cnblogs.com/de-compass/p/11748221.html

时间: 2024-07-31 13:59:29

cqyz oj | 罕见的秩序 | 拓扑排序的相关文章

【算法学习笔记】46.拓扑排序 优先队列 SJTU OJ 3010 Complicated Buttons

Description 凯恩在遗迹探险时遇到了n个按钮,刚开始所有按钮都处于开状态,凯恩的经验告诉他把所有按钮都关上会有“好事”发生,可是有些按钮按下时会让其他一些已经闭合的按钮弹开,经过凯恩研究,每个按钮都对应着一个固定的弹开集合,这个按钮按下时,弹开集合中所有的按钮都会变为开状态.现在小k想知道是否能让所有的按钮变为闭状态.如果能,打印最少步数以及方案,否则,打印“no solution”. Input Format 第一行一个整数n,表示n个按钮. 接下来n行,表示编号为1到n个按钮的弹开

hiho一下 第四十八周 拓扑排序&#183;二【拓扑排序的应用 + 静态数组 + 拓扑排序算法的时间优化】

题目1 : 拓扑排序·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho所在学校的校园网被黑客入侵并投放了病毒.这事在校内BBS上立刻引起了大家的讨论,当然小Hi和小Ho也参与到了其中.从大家各自了解的情况中,小Hi和小Ho整理得到了以下的信息: 校园网主干是由N个节点(编号1..N)组成,这些节点之间有一些单向的网路连接.若存在一条网路连接(u,v)链接了节点u和节点v,则节点u可以向节点v发送信息,但是节点v不能通过该链接向节点u发送信息. 在刚

拓扑排序(Topological Order)UVa10305 Ordering Tasks

2016/5/19 17:39:07 拓扑排序,是对有向无环图(Directed Acylic Graph , DAG )进行的一种操作,这种操作是将DAG中的所有顶点排成一个线性序列,使得图中的任意一对顶点u,v满足如下条件: 若边(u,v)∈E(G),则在最终的线性序列中出现在v的前面 好了,说人话:拓扑排序的应用常常和AOV网相联系,在一个大型的工程中,某些项目不是独立于其他项目的,这意味着这种非独立的项目的完成必须依赖与其它项目的完成而完成,不妨记为u,v,则若边(u,v)∈E(G),代

拓扑排序-图论

如果我们有一组任务完成,而有些任务人才的其他任务结束后开始.因此,我们必须非常小心,这些任务的运行顺序. 假设这些任务很简单的字的运行顺序,我们可以用它们来存储列表,这是一个非常好的方案,这样我们就可以知道运行秩序完全任务. 间的关系是非常复杂的.有些任务依赖于两个甚至很多其它的任务,或者反过来非常多任务依赖自己. 因此我们不能通过链表或者树的数据结构来对这个问题建模.对这类问题唯一合理的数据结构就是图.我们须要哪种图呢?非常显然,我们须要有向图来描写叙述这样的关系,并且是不能循环的有向图,我们

【日常学习】【拓扑排序】家谱树&amp;FZU1483 Sicily1424 奖金 题解

拓扑排序的定义 简单来说就是给你一个图写出一个序列 图中如果a通向b 那么序列中A必须排在B前面 拓扑排序可能有很多结果 必须是有向无环图 可以利用拓扑排序来判定环的存在 当然也可以用神奇的SPFA 但是拓扑排序时间复杂度很低 只有O(V+E) 基本实现思路是 每次取出入度为0的点 然后删除与它相连的边 直到没有边  如果还有边但是找不到入度为0的点 说明有环 学习这个算法联系了两道题目 很经典很单纯 但是一般没有OJ有评测 奖金这道题目在福州大学OJ和中山大学萌萌哒Sicily上找到了评测(为

HDU2647 Reward 【拓扑排序】

Reward Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3927    Accepted Submission(s): 1199 Problem Description Dandelion's uncle is a boss of a factory. As the spring festival is coming , he w

HDU1811 拓扑排序判环+并查集

HDU Rank of Tetris 题目:http://acm.hdu.edu.cn/showproblem.php?pid=1811 题意:中文问题就不解释题意了. 这道题其实就是一个拓扑排序判圈,我的博客里面其他几篇拓扑排序判圈的套路一样.但是这道题与他们不同的的是在大小关系里面存在一种 "="的关系,这就意味的那些序号不同的点,实际上是一个点.共享入度和出度.我们可以通过并查集将他们合并,合成一个点.这里说一下如何判断信息不完全.我们早先在做拓扑排序,多种排列方式的时候,按照字

ACM/ICPC 之 数据结构-邻接表+DP+队列+拓扑排序(TshingHua OJ-旅行商TSP)

做这道题感觉异常激动,因为在下第一次接触拓扑排序啊= =,而且看了看解释,猛然发现此题可以用DP优化,然后一次A掉所有样例,整个人激动坏了,哇咔咔咔咔咔咔咔~ 咔咔~哎呀,笑岔了- -|| 旅行商(TSP) Description Shrek is a postman working in the mountain, whose routine work is sending mail to n villages. Unfortunately, road between villages is

【图】拓扑排序

参考CSDN拓扑排序的原理及Java实现 拓扑排序C++实现 拓扑排序百度百科 若不是上了学堂在线的数据结构课程,我估计今后不做技术的话,都接触不到图的拓扑排序这个概念了.先是看了百度百科的解释,拓扑排序现实中的应用是选课,即某些课程需要一些先修课程的学习后才适合上.比如数据结构的学习,是离散数学.编程语言,后者是前者的先修课程. 拓扑排序定义:将有向无环图DAG中的顶点以线性方式进行排序.即对于任何连接自顶点u到顶点v的有向边uv,在最后的排序结果中,顶点u总是在顶点v的前面. 1.创建图: