2013NOIP普及组真题 4. 车站分级

news2024/10/7 3:25:03
线上OJ:

一本通:http://ybt.ssoier.cn:8088/problem_show.php?pid=1964

核心思想:

1、原文中提到 “如果这趟车次停靠了火车站 x,则始发站、终点站之间所有级别大于等于火车站 x 的都必须停靠”,如果设停靠站为A,未停靠站为B,则题意隐含公式 A > = B + 1 A >= B+1 A>=B+1。故本题为 差分约束 问题。
2、题中还提到 “输入保证所有的车次都满足要求”,所以本道题的差分约束问题 不存在环。且本题 不存在负权重。故可以采用 拓扑排序
3、由于在采用拓扑排序时,使用的是最短路算法,故需要 建立边。(关于差分约束和拓扑排序,可参见基础题型 一本通:奖金
● 本题中的顶点即为站点,由于隐含公式 A > = B + 1 A >= B+1 A>=B+1,所以要 在不停靠站点和停靠站点之间建立边,且权重为+1
● 由于有n个站点,所以需建立的边的最大数量为 ( n / 2 ) ∗ ( n / 2 ) = n 2 / 4 (n/2)*(n/2) = n^2/4 (n/2)(n/2)=n2/4
● 当 n 达到1000时, n 2 / 4 = 250000 n^2/4 = 250000 n2/4=250000。 也就是说每辆车最多建立 2.5 ∗ 1 0 5 2.5*10^5 2.5105条边,1000辆车就是 2.5 ∗ 1 0 8 2.5*10^8 2.5108 条边,会超时。

● 所以本题需要增加一个 虚拟原点,把不停靠和停靠的站点分割在两边(如下图所示)。这样可以把边的复杂度由 n ∗ m n*m nm 变为 n + m n+m n+m。也就是说,原本 ( n / 2 ) ∗ ( n / 2 ) (n/2)*(n/2) (n/2)(n/2) 的边的数量会变为 ( n / 2 ) + ( n / 2 ) (n/2)+(n/2) (n/2)+(n/2)。也就是说每辆车从最多建立 2.5 ∗ 1 0 5 2.5*10^5 2.5105条边,降到建立1000条边。1000辆车就是 1 0 6 10^6 106 条边,不会超时。

在这里插入图片描述

主流程

在这里插入图片描述

题解代码:
#include <bits/stdc++.h>

using namespace std;

const int MAXN = 2010;  // 真实站点的编号为 1 ~ n。虚拟站点的编号从 n 后面开始计算,每趟列车建立一个虚拟站点 n+i,最多到 n+m

int n, m, ans = 0;
// vis[i]=true 第i个站点被停靠; level[i]表示第i个车站的等级;du[i]表示第i个顶点的入度;e[v][j]=1 表示从v到j存在一条边; w[v][j]=1 表示从v到j的边的权重为1
int vis[MAXN], level[MAXN], du[MAXN], e[MAXN][MAXN], w[MAXN][MAXN];  
queue<int> q;

void toposort()
{
    // step1. 把所有入度为 0 的站点加入队列( n个真实站台 + m个虚拟站台 )
    for(int i = 1; i <= n + m; i ++)
    {
        if (du[i] == 0)
        {
            q.push(i);
            if(i <= n)  level[i] = 1; // 如果入度为 0 的是真实站点,说明这么多趟车都没有停靠该站点,则该站点等级设为1( 虚拟站台等级为0 )
        }
    }

    // step2. 栈顶元素v出栈;根据边 e[v][j]遍历 v 的每一个后继顶点 j
    while (!q.empty())
    {
        int v = q.front();  // 取出栈顶元素,放在 v
        q.pop();
        for (int j = 1; j <= n + m; j ++)  // 遍历所有顶点
        {
            if (e[v][j])  // 如果 v -> j 存在边
            {
                du[j]--;  // 减少 j 点的入度(相当于删除 v->j 这条边)
                if (du[j] == 0)  // 如果删除 v->j 边后,j 的入度变为 0,则j入栈;同时 level[v] 传递给 level[j]
                {
                    q.push(j);  
                    level[j] = level[v] + w[v][j];  // j的站点等级 = v的站点等级+边的权重
                }
            }
        }
    }
}

int main()
{
    scanf("%d%d", &n, &m);

    for(int i = 1; i <= m; i ++)
    {
        int s, start, en, t; // s:每辆列车有s个站点要停靠。start:起点站,en:终点站
        scanf("%d", &s);
        memset(vis, 0, sizeof(vis)); // vis[i]=1 表示第i个站点被停靠; vis[i]=0 表示第i个站点不停靠

        for(int j = 1; j <= s; j++) // 依次读入该趟列车的每个停靠站点
        {
            scanf("%d", &t);   // 存储在t
            vis[t] = 1;		   // vis[t]标记为停靠
            if (j == 1)  start = t;  // 第一个读入的是该趟列车的起点站,存储在start
            if (j == s)  en = t;     // 最后一个读入的是该趟列车的终点站,存储在en(end为关键字,故用en)
        }

        for(int j = start; j <= en; j++)  // 对该趟列车起点站和终点站之间的每个站点,根据是否停靠建立与虚拟站点的边
        {
            if(vis[j] == 1)  // 如果 j 号站点被停靠,则建立由虚拟站点 n+i 向 真实站点 j 的边,权值为1
            {
                e[n+i][j] = 1;	// 建立一条边,由虚拟站台 n+i -> j站台 
                w[n+i][j] = 1;  // 该边的权重为 1
                du[j]++;     // 真实站点 j 的入度 ++
            }
            else  // 如果 j 号站点没有被停靠,则建立由真实站点 j 向虚拟站点 n+i 的边,权值为0
            {
                e[j][n+i] = 1;	// 建立一条边,由 真实站点 j-> 虚拟站点 n+i ,边权为 0
                w[j][n+i] = 0;  // 该边的权重为 0
                du[n+i]++;	 // 虚拟站点 n+i 的入度++
            }
        }
    }

    toposort(); // 拓扑排序

    for(int i = 1; i <= n; i++)
        ans = max(ans, level[i]);
    cout << ans;
    return 0;
}

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

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

相关文章

汽车信息安全入门总结(2)

目录 1.引入 2.汽车信息安全技术 3.密码学基础知识 4.小结 1.引入 上篇汽车信息安全入门总结(1)-CSDN博客主要讲述了汽车信息安全应该关注的点&#xff0c;以及相关法规和标准&#xff0c;限于篇幅&#xff0c;继续聊信息安全相关技术以及需要掌握的密码学基础知识。 2.汽…

SpringCloud学习笔记(一)微服务介绍、服务拆分和RestTemplate远程调用、Eureka注册中心

文章目录 1 认识微服务1.1 单体架构1.2 分布式架构1.3 微服务1.4 SpringCloud1.5 总结 2 服务拆分与远程调用2.1 服务拆分原则2.2 服务拆分示例2.2.1 搭建项目2.2.2 创建数据库和表2.2.3 实现远程调用2.2.3.1 需求描述2.2.3.2 注册RestTemplate2.2.3.3 实现远程调用 2.2.4 提供…

Aiseesoft Data Recovery for Mac:专业数据恢复软件

Aiseesoft Data Recovery for Mac是一款高效且专业的数据恢复软件&#xff0c;专为Mac用户量身打造。 Aiseesoft Data Recovery for Mac v1.8.22激活版下载 无论是由于误删、格式化还是系统崩溃等原因导致的数据丢失&#xff0c;Aiseesoft都能帮助您快速找回。 它采用先进的扫描…

【计算机毕业设计】基于SSM++jsp的社区管理与服务系统【源码+lw+部署文档+讲解】

目录 摘 要 Abstract 第一章 绪论 第二章 系统关键技术 第三章 系统分析 3.1.1技术可行性 3.1.2经济可行性 3.1.3运行可行性 3.1.4法律可行性 3.4.1注册流程 3.4.2登录流程 3.4.3活动报名流程 第四章 系统设计 4.3.1登录模块顺序图 4.3.2添加信息模块顺序图 4.4.1 数据库E-…

SpringCloud系列(21)--更换Ribbon的负载均衡模式

前言&#xff1a;在上一篇文章中我们介绍了关于Ribbon的知识点已经如果去应用Ribbon&#xff0c;而本章节内容则是关于如何去切换Ribbon的负载均衡模式。 以下是上篇文章的部分内容&#xff0c;可以再看下熟悉下&#xff0c;方便后续理解 Ribbon工作架构图 Ribbon的负载均衡模式…

C# winform 漂亮的日期时间控件

源代码下载&#xff1a; https://download.csdn.net/download/gaoxiang19820514/89242240 效果图 在 HZH-Controls控件 基础上修改的日期控件 因为HZH_Controls控件 中的日期控件太大了&#xff0c; 我的程序中需要多个日期时间的控件放不下&#xff0c;主题是绿色的&#…

pkpmbs 建设工程质量监督系统 Ajax_operaFile.aspx 文件读取漏洞复现

0x01 产品简介 pkpmbs 建设工程质量监督系统是湖南建研信息技术股份有限公司一个与工程质量检测管理系统相结合的,B/S架构的检测信息监管系统。 0x02 漏洞概述 pkpmbs 建设工程质量监督系统 Ajax_operaFile.aspx接口处存在文件读取漏洞,未经身份认证的攻击者可以利用漏洞读…

使用 Docker 自建一款怀旧游戏之 - 扫雷

1&#xff09;扫雷 简介 扫雷 是一种经典的单人电脑游戏&#xff0c;最初由微软公司在 1990 年代开发并内置在 Windows 操作系统中。游戏的目标是在一个由方块组成的网格上揭开所有非地雷的方块&#xff0c;而不触发地雷。每个方块上都标有数字&#xff0c;表示周围 8 个方块中…

26版SPSS操作教程(高级教程第十七章)

目录 前言 粉丝及官方意见说明 第十七章一些学习笔记 第十七章一些操作方法 聚类分析 均值聚类法&#xff08;快速聚类法&#xff09; 假设数据 预分析&#xff08;描述统计&#xff09; 先将除了ID变量的每个变量除以其最大值进行标准化操作 具体操作 结果解释 聚…

OpenCV如何在图像中寻找轮廓

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV如何模板匹配 下一篇 :OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 目标 在本教程中&#xff0c;您将学习如何&#xff1a; 使用 OpenCV 函数 cv::findContour…

【Web】D^3CTF之浅聊d3pythonhttp——TE-CL请求走私

目录 step0 题目信息 step1 jwt空密钥伪造 step1.5 有关TE&CL的lab step2 TE-CL请求走私 payload1 payload2 step0 题目信息 注意到题目源码前端是flask写的&#xff0c;后端是web.py写的 frontend from flask import Flask, request, redirect, render_templat…

KMP算法与next数组【超详细】

一、朴素匹配法 S "abgabcd" T "abcd" 假设有两个字符串,要判断字符串T是否在字符串S中出现过&#xff0c;你会怎么做&#xff1f;一般来说我们都是这样&#xff0c;一个一个对比&#xff1a; #include<iostream> using namespace std; int mai…

机器学习:逻辑回归

概念 首先&#xff0c;逻辑回归属于分类算法&#xff0c;是线性分类器。我们可以认为逻辑回归是在多元线性回归的基础上把结果给映射到0-1的区间内&#xff0c;hθ&#xff08;x&#xff09;越接近1越有可能是正例&#xff0c;反之&#xff0c;越接近0越有可能是负例。那么&am…

C++中list的使用

文章目录 一、 list简介二、 构造函数1. 默认构造函数2. 拷贝构造3. 迭代器区间初始化4. 插入n个值为x的数据5. 代码示例 三、 容量和元素访问1. empty()2. size()3. max_size()3. back()4. front()5. 代码示例 四、 增删查改1. push_back()2. push_front()3. emplace_back()4.…

stm32f103zet6_串口实现-DHT11-tim1(定时)

1思路 1打开时钟 1.1使用定时器实现us级的计时 1.2在打开串口 1,3在DHT11驱动中修改引脚 stm32cudeMX 配置 1打开时钟 2打开串口 3打开tim1(定时器) 4生成代码 代码设置 1导入DHT11库(tim.h是定时器的文件系统自动生成的) DHT11.c #include "dht11.h" #inc…

机器学习:基于Sklearn、XGBoost框架,使用逻辑回归、支持向量机和XGBClassifier来诊断并预测一个人是否患有自闭症

前言 系列专栏&#xff1a;机器学习&#xff1a;高级应用与实践【项目实战100】【2024】✨︎ 在本专栏中不仅包含一些适合初学者的最新机器学习项目&#xff0c;每个项目都处理一组不同的问题&#xff0c;包括监督和无监督学习、分类、回归和聚类&#xff0c;而且涉及创建深度学…

nuxt3使用记录五:禁用莫名其妙的Tailwind CSS(html文件大大减小)

发现这个问题是因为&#xff0c;今天我突然很好奇&#xff0c;我发现之前构建的自动产生的200.html和404.html足足290k&#xff0c;怎么这么大呢&#xff1f;不是很占用我带宽&#xff1f; 一个啥东西都没有的静态页面&#xff0c;凭啥这么大&#xff01;所以我就想着手动把他…

爬虫实战-房天下(bengbu.zu.fang.com/)数据爬取

详细代码链接https://flowus.cn/hbzx/3c42674d-8e6f-42e3-a3f6-bc1258034676 import requests from lxml import etree #xpath解析库 def 源代码(url): cookies { global_cookie: xeqnmumh38dvpj96uzseftwdr20lvkwkfb9, otherid: b44a1837638234f1a0a15e…

Android Studio的笔记--布局文件

关于Layout布局文件的使用 LinearLayoutRelativeLayout之前文章的内容一些常见性质在android.graphics.Color中定义了12种常见的颜色常数线性布局LinearLayout 一些常见使用文本框TextView设置文本内容编辑框EditText获取文本内容按钮Button控件使用其他按钮修改图标及名称添加…

HEVC/H.265视频编解码学习笔记–框架及块划分关系

前言 由于本人在学习视频的过程中&#xff0c;觉得分块单元太多搞不清楚其关系&#xff0c;因此本文着重记录这些分块单元的概念以及关联。 一、框架 视频为一帧一帧的图像&#xff0c;其编码的主要核心是压缩空间以及时间上的冗余。因此&#xff0c;视频编码有帧内预测和帧间…