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

devtools/2024/10/21 10:13:53/
线上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+mint 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 的每一个后继顶点 jwhile (!q.empty()){int v = q.front();  // 取出栈顶元素,放在 vq.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);   // 存储在tvis[t] = 1;		   // vis[t]标记为停靠if (j == 1)  start = t;  // 第一个读入的是该趟列车的起点站,存储在startif (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;  // 该边的权重为 1du[j]++;     // 真实站点 j 的入度 ++}else  // 如果 j 号站点没有被停靠,则建立由真实站点 j 向虚拟站点 n+i 的边,权值为0{e[j][n+i] = 1;	// 建立一条边,由 真实站点 j-> 虚拟站点 n+i ,边权为 0w[j][n+i] = 0;  // 该边的权重为 0du[n+i]++;	 // 虚拟站点 n+i 的入度++}}}toposort(); // 拓扑排序for(int i = 1; i <= n; i++)ans = max(ans, level[i]);cout << ans;return 0;
}

http://www.ppmy.cn/devtools/32236.html

相关文章

《Beginning C++20 From Novice to Professional》第七章Working with Strings

字符串处理是非常令人关注的领域&#xff0c;因为大部分情况下我们的程序不是在处理数字而是在处理字符串&#xff0c;对于字符串的表示和操作成为编程语言中非常重要的一部分 书里也强调C中对于字符串的处理要好过C风格的char数组&#xff0c;更高效也更安全 本章我们可以学…

Matlab : unique函数的用法

unique是MATLAB中一个非常实用的函数&#xff0c;用于找出数组中的唯一值。它有几种不同的用法&#xff0c;可以根据需要选择合适的参数来控制输出的行为。以下是unique函数的基本用法和一些常见参数的介绍&#xff1a; 基本语法&#xff1a; C unique(A) [C,IA,IC] unique…

ATTCK的优缺点分别是什么

ATT&CK(Adversarial Tactics, Techniques, and Common Knowledge)框架是一个广泛使用的资源,它提供了对网络威胁的深入洞察,特别是关于攻击者可能采取的战术、技术和程序(TTPs)。以下是ATT&CK框架的优缺点: 优点: 全面的威胁情报:ATT&CK框架详细描述了各种…

redis集群的创建安装与配置,以及维护

一、redis集群配置 port 7000 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 appendonly yes 二、安装ruby&#xff08;ruby可以充当redis客户端的角色&#xff09; yum -y install ruby ruby-devel rubygems rpm-build gem install …

Big Data 平障录

Hive Hive 生成带压缩的格式&#xff0c;需要如此设置 SET parquet.compressionSNAPPY;yarn.scheduler.fair.assignmultiple 相关jira&#xff1a;https://issues.apache.org/jira/browse/YARN-5035 yarn.scheduler.fair.assignmultiple是YARN Fair Scheduler的一个配置参数…

人大金仓数据库的数据库系统的技术架构

人大金仓数据库作为中国社会科学院经济研究所主办的重要数据库平台&#xff0c;其数据库系统技术架构设计合理、稳定高效&#xff0c;为用户提供了丰富的数据资源和强大的数据分析功能。下面我将详细介绍人大金仓数据库的数据库系统技术架构。 1. 数据库系统概述 人大金仓数据…

Altium Designer入门基础操作

软件下载环境搭建&#xff1a;pan.baidu.com/s/1HshgKTmkkBpbIRa-9Wq9cQ 密码&#xff1a;ckck 工程建立&#xff1a; 创建 库绘制 为什么管脚要100mil 元素10mil 原理图库得正确性报告 原理图页设置大小&#xff0c;标准自定义&#xff0c;格点为100mil 使用库画原理图&a…

Linux变量的认识及环境变量配置详解

文章目录 1、变量的划分2、局部变量3、全局变量4、环境变量4.1、概述4.2、配置临时环境变量4.3、配置永久环境变量4.3.1、用户级配置文件1&#xff09;配置方法一&#xff1a;~/.bashrc文件2&#xff09;配置方法二&#xff1a;~/.profile文件3&#xff09;配置方法三&#xff…