首页 > 其他分享 >拓扑排序 学习笔记

拓扑排序 学习笔记

时间:2023-08-14 21:33:43浏览次数:55  
标签:int 拓扑 笔记 删去 ind 顶点 排序

模板题

分析题目

求一个图的拓扑序。需要用到拓扑排序。

拓扑排序

将一张图中的顶点以线性方式进行排序,使得对于任何的顶点 \(u\) 到 \(v\) 的有向边 \((u,v)\), 都可以有 \(u\) 在 \(v\) 的前面。
并且拓扑排序只能在有向无环图(DAG)中完成。

做法:每次找到入度为 \(0\) 的顶点,将这个顶点列入拓扑序中,并将这个顶点及其相连的边删去。
删去之后再找到入度为 \(0\) 的顶点,重复以上操作,直到所有点都被删去。至此拓扑排序完成。

代码

BFS

考虑建图时开一个数组 \(ind\),\(ind_i\) 表示编号为 \(i\) 的顶点的入度数量。
然后进行拓扑排序:
定义一个队列 \(q\) 为上一次操作中被删去的入度为 \(0\) 的点。
首先遍历 \(ind\) 数组,找出入度为 \(0\) 的顶点,存入队列 \(q\),并纳入拓扑序。
每次取出 \(q\) 的队首,遍历它所有的出边,将与它相连的所有顶点的 \(ind\) 减去 \(1\)(相当于删去与它相连的边的操作)。判断如果 \(ind_i=0\),那么将这个点也放入队列中等待操作,并也将这个点纳入拓扑序。
重复操作,直到队列为空(整个过程相当于BFS)。

代码实现:

#include <bits/stdc++.h>
#define int long long
const int N = 1005;
using namespace std;
inline int read(){
    int r = 0,w = 1;
    char c = getchar();
    while (c < '0' || c > '9'){
        if (c == '-'){
            w = -1;
        }
        c = getchar();
    }
    while (c >= '0' && c <= '9'){
        r = (r << 3) + (r << 1) + (c ^ 48);
        c = getchar();
    }
    return r * w;
}
struct edge{
	int nxt,to;
}e[N];
int cnt = 0,head[N];
void edge_add(int x,int y){
	cnt++;
	e[cnt].nxt = head[x];
	head[x] = cnt;
	e[cnt].to = y;
}
int n,ind[N];
void topo(){
	queue<int>q;
	for (int i = 1;i <= n;i++){
		if (!ind[i]){
			q.push(i);
			printf("%lld ",i);
		}
	}
	while (!q.empty()){
		int tmp = q.front();
		q.pop();
		for (int i = head[tmp];i;i = e[i].nxt){
			int v = e[i].to;
			ind[v]--;
			if (!ind[v]){
				q.push(v);
				printf("%lld ",v);
			}
		} 
	}
}
signed main(){
	n = read();
    for (int i = 1;i <= n;i++){
    	int x = read();
    	while (x){
    		edge_add(i,x);
    		ind[x]++;
    		x = read();
		}
	}
	topo();
    return 0;
}

标签:int,拓扑,笔记,删去,ind,顶点,排序
From: https://www.cnblogs.com/WiuehPlus/p/17629816.html

相关文章

  • 新人笔记-方法重载基本知识
    方法重载:多个方法在同一个类中多个方法具有相同的方法名多个方法的参数不相同,类型不同或者数量不同与返回值无关在调用时,Java虚拟机会通过参数的不同来区分同名的方法publicclassMethodDemo02{publicstaticvoidmain(String[]args){in......
  • 新人笔记-参数的传递
    publicclassMethodDemo03{publicstaticvoidmain(String[]args){intnumber=100;System.out.println("调用方法前"+number);change(number);System.out.println("调用方法后"+number);}publicsta......
  • 『学习笔记』插入类dp
    概述可以说是一个套路化问题,想出来了就非常好做。前提是你得想出来。转移方程一般也都是特定的:设\(dp_{i,j}\)表示往一个序列里插入了\(i\)个数,这\(i\)个数被分成了\(j\)段的方案数。初始化:\(\begin{cases}dp_{1,i=1}=1\\dp_{1,i\ne1}=0\end{cases}\).......
  • table排序
    <el-tablev-loading="fourthloading":data="tableData4"style="width:100%"height="390"  @sort-change="sortChange"ref="fourthtable">//@sort-change  <el-table-columnprop="ti......
  • 学习笔记 - Java 数组
    数组的概述数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。数组是有序排列的,且数组属于引用数据类型,但数组中的元素既可以是基本数据类型,又可以是引用数据类型。数组的存储是在内存中开启一片连续的空间,长度一旦......
  • openGauss学习笔记-39 openGauss 高级数据管理-分区表
    openGauss学习笔记-39openGauss高级数据管理-分区表一张表内的数据过多时,就会严重影响到数据的查询和操作效率。openGauss支持把一张表从逻辑上分成多个小的分片,从而避免一次处理大量数据,提高处理效率。openGauss数据库支持这些划分类型:范围分区表:指定一个或多个列划分为多个......
  • 大数据处理之高效查询频度排序
    引言在互联网时代,数据量的爆炸增长给数据处理带来了巨大的挑战。本文将介绍如何高效地处理10个每个文件大小为1G的文件,其中每个文件的每一行存放的都是用户的查询(query)。我们的目标是按照查询的频度对这些查询进行排序。为了解决这个问题,我们将借助大数据处理技术,并给出代码示例......
  • 前端进化笔记-JavaScript(四)
    生活想要将我活埋,怎料我是一颗种子基本引用类型对象是引用类型的实例:new后面跟一个构造函数就创建了一个新对象,例如letnow=newDate();,这样就创建了一个Date对象.Date类型方法Date.parse():根据传入的参数返回毫秒数。参数为有固定格式的表示日期的字符串。Date.UTC():......
  • 华为Datacom 综合拓扑案例—分享篇
    拓扑图题目要求实验要求:1、PC1\PC2\PC3\PC4采用DHCP自动获取IP地址,SW5作为服务器,SW3和SW4作为中继创建地址池ippoolhuawei1和ippoolhuawei2,租期都为2天2、SW3与SW4做链路聚合,采用LACP模式。SW3作为主交换机,优先级为0抢占延时时间为10秒让G0/0/4接口成为非活跃链路,优先级为65000......
  • [YsOI2023] 广度优先遍历 逆向输出路径(分层建树拓扑序. LCA)
    今天的模板测试是无向图上的广度优先遍历,【数据删除】马上写好了代码:1#include<cstdio>2#include<cstring>3#include<iostream>4#include<algorithm>5#include<vector>6#include<queue>7usingnamespacestd;8constintmaxn=100005;......