第三章 图论 No.13拓扑排序

news2024/11/25 18:37:57

文章目录

      • 裸题:1191. 家谱树
      • 差分约束+拓扑排序:1192. 奖金
      • 集合+拓扑序:164. 可达性统计
      • 差分约束+拓扑序:456. 车站分级

拓扑序和DAG有向无环图联系在一起,通常用于最短/长路的线性求解
image.png

裸题:1191. 家谱树

1191. 家谱树 - AcWing题库
image.png

#include <iostream>
#include <cstring>
using namespace std;

const int N = 110, M = 10010;
int h[N], e[M], ne[M], idx;
int d[N], q[N], hh, tt = -1;
int n, m;

void add(int x, int y)
{
    e[idx] = y, ne[idx] = h[x], h[x] = idx ++ ;
}

void topsort()
{
    for (int i = 1; i <= n; ++ i )
        if (!d[i]) q[ ++ tt ] = i;
    while (tt >= hh )
    {
        int x = q[hh ++ ];
        for (int i = h[x]; i != -1; i = ne[i])
        {
            int y = e[i];
            if (-- d[y] == 0) q[++ tt] = y;
        }
    }
}

int main()
{
    memset(h, -1, sizeof(h));
    scanf("%d", &n);
    for (int x = 1; x <= n; ++ x )
    {
        int y;
        while (scanf("%d", &y), y)
        {
            add(x, y);
            d[y] ++ ;
        }
    }
    
    topsort();
    for (int i = 0; i <= tt; ++ i )
        printf("%d ", q[i]);
    return 0;
}

差分约束+拓扑排序:1192. 奖金

1192. 奖金 - AcWing题库
image.png

由于图中所有边权都是正数,可以直接使用topsort求解差分约束问题
根据题意,要求一个最小值,使用最长路求解,转化题目的条件: A > = B + 1 A >= B + 1 A>=B+1 x i > = x 0 + 100 x_i >= x_0 + 100 xi>=x0+100
x 0 x_0 x0为一个虚拟源点,向每个点连了一条权值为100的边

若图中存在环,topsort的队列长度将小于n,因为环的起点无法进入队列
先用topsort判断图中是否存在环,若不存在,根据拓扑序遍历图,求解最长路

#include <iostream>
#include <cstring>
using namespace std;

const int N = 10010, M = 30010;
int h[N], e[M], ne[M], w[M], idx;
int q[N], d[N], hh, tt = -1;
int dis[N];
int n, m;

void add(int x, int y, int d)
{
    e[idx] = y, ne[idx] = h[x], w[idx] = d, h[x] = idx ++ ;
}

bool topsort()
{
    q[ ++ tt ] = 0;
    while (tt >= hh)
    {
        int x = q[hh ++ ];
        for (int i = h[x]; i != -1; i = ne[i] )
        {
            int y = e[i];
            if ( -- d[y] == 0) q[ ++ tt ] = y;
        }
    }
    return tt == n;
}

int main()
{
    memset(h, -1, sizeof(h));
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; ++ i )
    {
        int x, y;
        scanf("%d%d", &x, &y);
        add(y, x, 1);
        d[x] ++ ;
    }
    
    for (int i = 1; i <= n; ++ i ) add(0, i, 100), d[i] ++ ;
    if (!topsort()) puts("Poor Xed");
    else 
    {
        for (int k = 0; k <= tt; ++ k )
        {
            int x = q[k];
            for (int i = h[x]; i != -1; i = ne[i])
            {
                int y = e[i];
                dis[y] = max(dis[y], dis[x] + w[i]);
            }
        }
        int sum = 0;
        for (int i = 1; i <= n; ++ i ) sum += dis[i];
        printf("%d\n", sum);
    }
    
    return 0;
}

debug:最后的遍历没有按照拓扑序

for (int x = 0; x <= tt; ++ x )
{
	for (int i = h[x]; i != -1; i = ne[i])
	{
		int y = e[i];
		dis[y] = max(dis[y], dis[x] + w[i]);
	}
}

集合+拓扑序:164. 可达性统计

[164. 可达性统计 - AcWing题库](https://www.acwing.com/problem/content/description/166/
image.png

从集合的角度思考, f ( i ) f(i) f(i)表示i这个点能到达的所有点,i首先能到达自己,其次能达到 f ( j 1 ) , f ( j 2 ) , . . . , f ( j n ) f(j_1), f(j_2), ... , f(j_n) f(j1),f(j2),...,f(jn),假设i与n个点直接相连
那么要求 f ( i ) f(i) f(i),就必须求出 f ( j 1 ) , f ( j 2 ) , . . . , f ( j n ) f(j_1), f(j_2), ... , f(j_n) f(j1),f(j2),...,f(jn),即拓扑排序中位于i之后的所有点的 f ( j ) f(j) f(j)
所以这题先拓扑排序,再根据拓扑排序的逆序,求 f ( i ) f(i) f(i)
如何表示集合 f ( i ) f(i) f(i)?用STL的容器bitset,假设图中有N个点,那么bitset的长度为N,每个点都用一个bitset记录其集合,1表示i能递达这个点,0表示不能递达
那么 f ( i ) = f ( j 1 ) ∩ f ( j 2 ) ∩ . . . ∩ f ( j n ) f(i) = f(j_1)∩ f(j_2)∩ ...∩f(j_n) f(i)=f(j1)f(j2)...f(jn)

关于bitset的使用,bitset之间支持|=运算,count()输出bitset中1的个数

#include <iostream>
#include <cstring>
#include <bitset>
using namespace std;

const int N = 30010, M = N;
int h[N], e[M], ne[M], idx;
int q[N], d[N], hh, tt = -1;
bitset<N> f[N];
int n, m;

void add(int x, int y)
{
    e[idx] = y, ne[idx] = h[x], h[x] = idx ++ ;
}

void topsort()
{
    for (int i = 1; i <= n; ++ i )
        if (!d[i]) q[ ++ tt ] = i;
    while (tt >= hh)
    {
        int x = q[hh ++ ];
        for (int i = h[x]; i != -1; i = ne[i])
        {
            int y = e[i];
            if ( -- d[y] == 0) q[ ++ tt ] = y;
        }
    }
}

int main()
{
    memset(h, -1, sizeof(h));
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; ++ i )
    {
        int x, y;
        scanf("%d%d", &x, &y);
        add(x, y);
        d[y] ++ ;
    }
    topsort();
    
    for (int i = tt; i >= 0; -- i )
    {
        int x = q[i];
        f[x][x] = 1;
        for (int i = h[x]; i != -1; i = ne[i])
        {
            int y = e[i];
            f[x] |= f[y];
        }
    }
    for (int i = 1; i <= n; ++ i ) printf("%d\n", f[i].count());

    return 0;
}

差分约束+拓扑序:456. 车站分级

456. 车站分级 - AcWing题库
image.png

分析题意:对于每一条路线,未经过的站点的等级一定小于经过的站点等级,并且最低的站点等级为1级
题目要求所有等级划分中的最少等级数,用最长路求最小值。将以上条件转换成差分约束中的两个条件: B > = A + 1 B >= A + 1 B>=A+1, x i > = x 0 + 1 x_i >= x_0 + 1 xi>=x0+1
x 0 x_0 x0为虚拟源点,通过 x 0 x_0 x0能到达图中的所有点,那么就一定能递达所有边

由于每条路线路都会建立n * m条边,极端情况下可能会爆空间,所以考虑如何优化
一条路径中未经过的站点将向经过的站点连接一条权值为1的边,一共n * m条,由于这些边的权值相同,可以在这些边中创建一个虚拟点v,未经过的点分别向v连一条权值为0的边,v向经过的点分别连接一条权值为1的边。这样,从未经过的点到经过的点的权值和依然为1,但是需要建立的边数为n + m,此时的边数在极端情况下也不会爆空间

#include <iostream>
#include <cstring>
using namespace std;

const int N = 2010, M = 1e6 + 10;
int h[N], e[M], ne[M], w[M], idx;
int d[N], q[N], hh, tt = -1;
bool st[N]; int dis[N];
int n, m;

void add(int x, int y, int d)
{
    e[idx] = y, ne[idx] = h[x], w[idx] = d, h[x] = idx ++ ;
}

void topsort()
{
    for (int i = 1; i <= n + m; ++ i ) 
        if (!d[i]) q[ ++ tt ] = i;
    while (tt >= hh)
    {
        int x = q[hh ++ ];
        for (int i = h[x]; i != -1; i = ne[i])
        {
            int y = e[i];
            if (-- d[y] == 0) q[ ++ tt ] = y;
        }
    }
}

int main()
{
    memset(h, -1, sizeof(h));
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= m; ++ i )
    {
        memset(st, false, sizeof(st));
        int t, start = n, end = 0;
        scanf("%d", &t);
        while (t -- )
        {
            int x;
            scanf("%d", &x);
            st[x] = true;
            start = min(start, x), end = max(end, x);
        }
        int v = n + i;
        for (int i = start; i <= end; ++ i )
        {
            if (st[i]) add(v, i, 1), d[i] ++ ;
            else add(i, v, 0), d[v] ++ ;
        }
    }
    
    topsort();
    for (int i = 1; i <= n; ++ i ) dis[i] = 1;
    for (int i = 1; i <= tt; ++ i )
    {
        int x = q[i];
        for (int i = h[x]; i != -1; i = ne[i])
        {
            int y = e[i];
            dis[y] = max(dis[y], dis[x] + w[i]);
        }
    }
    int res = 0;
    for (int i = 1; i <= n; ++ i ) res = max(res, dis[i]);
    printf("%d\n", res);
    
    return 0;
}

debug:w[M]写成了w[N],又是这样,然后debug了半天,了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/881717.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用PDF文件入侵任何操作系统

提示&#xff1a;我们8月28号开学,所以我得快点更新了&#xff0c;不能拖了&#x1f625; 文章目录 前言一、打开终端总结 前言 PDF文件被广泛应用于共享信息&#xff0c;电子邮件&#xff0c;网站或文档或存储系统的真实链接 它可以用于恶意软件的载体。 不要问我什么意思&am…

Spring学习笔记(思维导图)

目录 基本概念 Spring优点&#xff1a; Spring缺点&#xff1a; AOP 实现原理&#xff1a; Jdk动态代理&#xff1a; CGlib: 静态代理&#xff1a; JDK动态代理和CGlib的对比&#xff1a; 配置方式&#xff1a; 基本概念&#xff1a; 事务管理 基本概念 事务控制 事…

Bingchat和ChatGPT主要区别

Bing Chat由chatgpt GPT-4技术提供支持&#xff0c;这是流行的ChatGPT的最新语言模型。Bing Chat通过更具交互性和上下文联动的响应来优化搜索引擎。它允许用户提出问题并获得更人性化、精确化或创造力的答案。用户还可以在答案末尾查看的参考来源。该工具可以充当个人研究、计…

每天一个知识点——L2R

面试的时候&#xff0c;虽然做过医疗文献搜索&#xff0c;也应用过L2R的相关模型&#xff0c;但涉及到其中的一些技术细节&#xff0c;都会成为我拿不下offer永远的痛。也尝试过去理解去背下一些知识点&#xff0c;终究没有力透纸背&#xff0c;随着时间又开始变得模糊&#xf…

Mysql使用数据类型为datetime导致无法返回规定格式解决

Mysql使用数据类型为datetime&#xff0c;在java中使用Date获取到返回的实际是一个秒数。 1.可以通过注解JsonFormat 直接转换成对应格式 pattern&#xff1a;格式 timezone&#xff1a;时区 2.手动转换&#xff0c;封装方法 /** * 时间转yyyy-MM-dd HH:mm:ss * * return */ …

【产品人卫朋】硬件产品经理:产品成功的四个要素

目录 要素一&#xff1a;快速行动 要素二&#xff1a;衡量产品增长力 了解你的目标用户 衡量用户参与度 要素三&#xff1a;避免浪费金钱 要素四&#xff1a;组建一支能打的团队 硬件产品的成功离不开四个核心要素&#xff0c;分别是&#xff1a; &#xff08;1&#xf…

消防二维码管理系统搭建教程

针对消防管理中普遍存在的消防设施巡查、维修、报修等需求&#xff0c;可以在草料二维码上搭建消防管理二维码系统&#xff0c;为每个消防设施生成一张独立的二维码&#xff0c;实现微信扫码进行巡检、维修、隐患上报等功能。 系统搭建流程 消防管理二维码系统由一个个二维码…

无涯教程-Perl - setservent函数

描述 在第一次调用getservent之前,应先调用此函数。 STAYOPEN参数是可选的,在大多数系统上未使用。当getservent()检索服务数据库中下一行的信息时,然后setervent设置(或重置)枚举到主机条目集的开头。 语法 以下是此函数的简单语法- setservent STAYOPEN返回值 此函数不返…

安防视频监控汇聚平台EasyCVR视频监控综合管理平台接入Ehome告警,公网快照不显示的问题解决步骤

智能视频监控汇聚平台TSINGSEE青犀视频EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等&#xff0c;视频监控管理平台…

Compute shader SV 理解图

本图转子&#xff1a;【Computeshader】个人总结_蒋伟博的博客-CSDN博客

Spring解决循环依赖问题

一、什么是循环依赖&#xff1f; 例如&#xff0c;就是A对象依赖了B对象&#xff0c;B对象依赖了A对象。&#xff08;下面的代码属于属性的循环依赖&#xff0c;也就是初始化阶段的循环依赖&#xff0c;区别与底下构造器的循环依赖&#xff09; // A依赖了Bclass A{public B b;…

什么是CNN(卷积神经网络)

什么是卷积神经网络 卷积神经网络(Convolutional Neural Network)&#xff0c;在一个个填充着数字的正方形小格子&#xff0c;它们被称为卷积核。 原始图片经过输入层后&#xff0c;会变为灰度或是RGB数值填充的矩阵 将卷积核与图片矩阵对齐&#xff0c;对应格子中的数字相乘后…

Dev-C++

文章目录 介绍使用教程常用快捷键文件部分格式部分行操作跳转部分显示部分运行部分调试部分 调试流程 扩展增加编译选项开启优化显示最多警告信息生成调试信息 编译小 trick开大栈定义宏代码格式化 美化字体主题 介绍 Dev-C 是一套用于开发 C/C 程序的自由的集成开发环境&…

信贷行业如何找精准客户的(贷款大数据获客) ?

现在是互联网时代&#xff0c;大数据是指所有社会发展管理体系和经济发展框架中的许多数据信息来源&#xff0c;通常意味着当前的经济环境或市场需求&#xff0c;根据贷款行业三网运营商数据客户资源可以立即计算未来的经济发展趋势&#xff0c;可以让各领域的公司找到生存和发…

哈中盛会,融通互鉴|哈萨克斯坦-中国商业交流论坛引领新合作

为促进哈萨克斯坦与中国商业贸易的交流合作&#xff0c;8月14日&#xff0c;由深圳市跨境电商供应链服务协会、哈萨克斯坦-中国贸易促进协会和跨播集团联合主办的“哈萨克斯坦-中国商业交流论坛”在深圳大中华希尔顿酒店成功举办。哈萨克斯坦共和国副总理兼贸易和一体化部部长朱…

财务数据分析之现金流量表模板分享

现金流量表是我们常说的财务数据分析三表之一。它可以呈现一个企业的现金流情况&#xff0c;揭示企业经营管理健康状态&#xff0c;但在实际使用中却有总给人一种用不上、用不好的矛盾感。怎么才能把现金流量表做好&#xff1f;不如借鉴下大神的现金流量表模板。 下面介绍的是…

【应用笔记】使用 CW32 实现电池备份(VBAT)功能

前言 电池备份&#xff08;VBAT&#xff09;功能的实现方法&#xff0c;一般是使用 MCU 自带的 VBAT 引脚&#xff0c;通过在该引脚连接钮扣电池&#xff0c;当系统电源因故掉电时&#xff0c;保持 MCU 内部备份寄存器内容和 RTC 时间信息不会丢失。 本文档介绍了如何基于 C…

iShot Pro for Mac 2.3.9最新中文版

iShot Pro是一款非常优秀的Mac截图软件&#xff0c;软件非常易于操作&#xff0c;主页面还设置了学习教程&#xff0c;可以轻松玩转软件所有功能&#xff0c;并且功能非常强大&#xff0c;不仅可以实现多种截图方式&#xff0c;还可以进行标注、贴图、取色、录屏、录音、OCR识别…

专为茶叶品牌设计的美观小程序制作教程分享

茶叶是中国传统的饮品&#xff0c;拥有悠久的历史和丰富的文化内涵。而如今&#xff0c;随着互联网的快速发展&#xff0c;许多茶叶品牌也开始转向线上销售&#xff0c;以便更好地满足消费者的需求。为了方便茶叶品牌与消费者之间的互动&#xff0c;设计一个美观的小程序是必不…

前后端分离------后端创建笔记(09)密码加密网络安全

本文章转载于【SpringBootVue】全网最简单但实用的前后端分离项目实战笔记 - 前端_大菜007的博客-CSDN博客 仅用于学习和讨论&#xff0c;如有侵权请联系 源码&#xff1a;https://gitee.com/green_vegetables/x-admin-project.git 素材&#xff1a;https://pan.baidu.com/s/…