洛谷 P1347 排序(福建省历届夏令营)(图论:拓扑排序)

题目描述

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

输入格式

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

说明/提示

2≤n≤26,1≤m≤600。

这道题考察的是拓扑排序,AcWing 1191. 家谱树(图论,拓扑排序的模板)-CSDN博客 模板在这

我们简单讲讲思路,我们把输出分成三种形式(题目描述先后对应1、2、3),第1种是可以判断得出完整拓扑排序的情况,第2种是有环的情况,第3种就是这两个之外直接输出

第2种:首先判断是否形成环了,做法:记录出现的字母个数,如果最后得到的拓扑序列的大小 小于字母个数,那么就是形成环了

第1种:必须严格的得出所有字母之间的关系,也就是说记录出现字母的个数必须等于拓扑序列的大小而且队列的大小要保持为1,如果超过1了说明有不确定的关系

代码:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

const int N = 30;
int ind[N],oud[N],cpy[N];
vector<int> e[N];
bool b[N];

int n,m,cnt = 0,type = 0;

void topsort(int idx){
    memcpy(ind,cpy,sizeof(cpy));
    queue<int> q;
    string ans = "";
    bool ac = true;
    for(int i=1;i<=n;i++){
        if(!b[i]) continue;
        if(!ind[i]) q.push(i);
    }
    while(!q.empty()){
        if(q.size() >= 2) ac = false;
        int u = q.front();
        q.pop();
        ans += char(u) + 64;
        for(auto v : e[u]){
            ind[v] --;
            if(!ind[v]) q.push(v);
        }
    }
    // if(idx == 28) cout << ans << " " << ans.size() << " " << cnt << endl;
    if(ans.size() < cnt){
        // cout << ans.size() << " " << cnt << endl;
        type = 2;
        printf("Inconsistency found after %d relations.\n",idx);
    }
    if(ans.size() == n && ac){
        type = 1;
        printf("Sorted sequence determined after %d relations: ",idx);
        cout << ans << "." << endl;
    }
}

int main()
{
    cin >> n >> m;
    string s;
    for(int i=1;i<=m;i++){
        cin >> s;
        if(type) continue;
        int A = s[0] - 64,B = s[2] - 64;
        // cout << A << " " << B << endl;
        if(!b[A]){
            b[A] = true;
            cnt ++;
        }
        if(!b[B]){
            b[B] = true;
            cnt ++;
        }
        if(s[1] == '<'){
            cpy[B] ++,oud[A] ++;
            e[A].push_back(B);
        }else{
            cpy[A] ++,oud[B] ++;
            e[B].push_back(A);
        }
        topsort(i);
    }
    if(!type) cout << "Sorted sequence cannot be determined." << endl;
    return 0;
}

加油

相关推荐
FanXing_zl2 分钟前
快速掌握线性代数:核心概念与深度解析
线性代数·算法·机器学习
zzzsde16 分钟前
【C++】红黑树:使用及实现
开发语言·c++·算法
点云SLAM20 分钟前
C++ 中的栈(Stack)数据结构与堆的区别与内存布局(Stack vs Heap)
开发语言·数据结构·c++·内存布局·栈数据结构·c++标准算法·heap内存分配
码界奇点22 分钟前
Linux进程间通信三System V 共享内存完全指南原理系统调用与 C 封装实现
linux·c语言·网络·c++·ux·risc-v
小无名呀38 分钟前
tcp_Calculator(自定义协议,序列化,反序列化)
网络·c++·网络协议·tcp
AA陈超41 分钟前
ASC学习笔记0001:处理目标选择系统中当Actor拒绝目标确认时的调用
c++·笔记·学习·游戏·ue5·游戏引擎·虚幻
Kuo-Teng1 小时前
LeetCode 139: Word Break
java·算法·leetcode·职场和发展·word·动态规划
Algor_pro_king_John1 小时前
模板ACM
算法·图论
前端小L1 小时前
图论专题(六):“隐式图”的登场!DFS/BFS 攻克「岛屿数量」
数据结构·算法·深度优先·图论·宽度优先
-大头.1 小时前
Python数据结构之旅:09-图论基础——连接万物的网络
数据结构·图论