label 拓扑排序

题目描述

有N个球,重量从1到N,各不相同,每个球有个编号也是从1到N,各不相同。现在给你一些约束条件,每个约束条件给出数字A,B,表示A号球轻于B号球。请你求出满足约束条件的某个球的重量的全排列,注意如果有多个排列满足条件,我们希望1号球的重量越小越好;当1号球的重量一样时,希望2号球的重量越小越好; 当2号球的重量一样时,希望3号球的重量越小越好......

输入

第一行给出数字N,M,代表有N个球,M个约束条件N (1 ≤ N ≤ 200) , M (0 ≤ M ≤ 40,000).下面将有M行,每行两个数字A,B,(1 ≤ a, b ≤ N)表示A号球轻于B号球。

输出

依次输出从1号球到N号球的重量,任两个数字之间以一个空格格开,无解时输出-1。

样例输入

复制

复制代码
【样例1】
4 1
3 2
【样例2】
6 3
2 4
4 3
4 6
样例输出

复制

复制代码
【样例1】
1 3 2 4
【样例2】
1 2 4 3 5 6
1.拓扑排序(Topological Sorting)

是对**有向无环图(DAG)**的顶点进行线性排序,使得对于图中的每一条有向边 u → v,顶点 u 都排在顶点 v 的前面。

(上次的苹果也是拓扑排序)

2. 算法步骤(Kahn算法)

  1. 初始化

    • 计算每个顶点的入度(指向它的边的数量)。

    • 将入度为 0 的顶点加入队列(或堆)。

  2. 处理队列

    • 取出队首顶点 u,加入拓扑序。priority_queue

    • 遍历 u 的所有邻接顶点 v

      • v 的入度减 1

      • v 的入度变为 0,将其加入队列。

  3. 检查环

    • 若拓扑序的顶点数 ≠ 总顶点数,则图中存在环,无拓扑序。

5. 变种:字典序最小拓扑序

  • 最小堆 :每次选编号最小的入度为 0 的顶点。

  • 最大堆 :每次选编号最大的入度为 0 的顶点(用于反向图)。

"重量序列" 指的是按重量从小到大的顺序排列的球的编号 。例如,若重量 1 对应 3 号球,重量 2 对应 1 号球,重量 3 对应 2 号球,则重量序列为 [3,1,2](即重量 1 是 3 号,重量 2 是 1 号,重量 3 是 2 号)。

"字典序最小" 指的是这个序列在字典排序中最小(类似字典中单词的排序)。例如 [1,2,3][1,3,2] 小,因为第二个位置 2 < 3。

如果用正向拓扑排序(小顶堆选最小编号),得到的是重量序列的字典序最小 。此时++优先保证 "重量从小到大对应的球编号尽可能小",但无法保证 "1 号球的重量尽可能小"。++

"球编号序列" 指的是按球的编号顺序(1→2→...→N)排列的重量 。例如,1 号球的重量是 2,2 号球的重量是 3,3 号球的重量是 1,则编号序列的重量为 [2,3,1](即 1 号重 2,2 号重 3,3 号重 1)。

"球编号序列的重量最小" 指的是按编号顺序,每个位置的重量尽可能小(先保证 1 号最小,再保证 2 号最小,以此类推),这正是题目要求的目标。

deepsleep了

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
int n,m,a,b,ind[210],c[210][210]{0};
int main(){
	cin>>n>>m;
	vector<vector<int>>adj(n+1);
	for(int i=0;i<m;++i){
		cin>>a>>b;
		if(c[a][b])continue;
		c[a][b]=1;
		adj[b].push_back(a);
		ind[a]++;
	}
	priority_queue<int>who;
	for(int i=1;i<=n;++i){
		if(ind[i]==0)who.push(i);
	}
	vector<int>ans;
	while(!who.empty()){
		int x=who.top();
		ans.push_back(x);
		who.pop();
		for(auto i:adj[x]){
			ind[i]--;
			if(ind[i]==0){
				who.push(i);				
			}
		}
	}
	if(ans.size()!=n){
		cout<<"-1";return 0;
	}
	int w[210]{0},x=n;
	for(auto i:ans){
		w[i]=x--;
	}
	for(int i=1;i<=n;++i){
		cout<<w[i]<<" ";
	}
	return 0;
}
相关推荐
AI 嗯啦7 分钟前
机械学习--逻辑回归
算法·机器学习·逻辑回归
山烛19 分钟前
逻辑回归详解:从数学原理到实际应用
python·算法·机器学习·逻辑回归
爱煲汤的夏二1 小时前
扩展卡尔曼滤波器 (EKF) 与无人机三维姿态估计:从理论到实践
单片机·嵌入式硬件·算法·无人机
sali-tec1 小时前
C# 基于halcon的视觉工作流-章27-带色中线
开发语言·人工智能·算法·计算机视觉·c#
范特西_1 小时前
字典树/前缀树
c++·算法
GeekPMAlex1 小时前
Langchain/Langgraph知识点1
算法
MPCTHU1 小时前
决策树实现回归任务
算法·决策树·回归
sheepwjl2 小时前
《嵌入式C语言笔记(十七):进制转换、结构体与位运算精要》
linux·c语言·开发语言·笔记·算法
修钩.2 小时前
力扣 Pandas 挑战(5)---数据分组
算法·leetcode·pandas
xiaobaibai1532 小时前
烟草复杂包装识别准确率↑31%!陌讯多模态SKU检测算法在零售终端的实战解析
人工智能·算法·视觉检测·边缘计算·零售