「JSOI2010」排名

传送门

看到先后顺序限制和字典序,很容易想到拓扑排序 + 贪心。

考虑具体做法:

对于第一问:

我们开一个大根堆来代替队列,然后从大到小构造出各个元素的排名。

我们连边 \(i \to a_i\) ,表示 \(i\) 要在 \(a_i\) 后面,也就是满足 \(a_i\) 在 \(i\) 前面。

然后我们拓扑排序的时候每次取出的都是当前编号最大的并把它放在后面,也就满足了字典序尽量小的原则。

对于第二问:

我们还是考虑用堆来代替队列,但此时是要使得字典序尽量大,所以我们改为连边 \(a_i \to i\) ,然后从小到大构造排名即可。

(p.s. 但是这题数据好奇怪啊,我一开始在第二问的拓扑排序里面,写成每个节点直接往堆里丢,居然也过了???)

参考代码:

#include <cstring>
#include <cstdio>
#include <queue>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
using namespace std;
template < class T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while ('0' > c || c > '9') f |= c == '-', c = getchar();
while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
s = f ? -s : s;
} const int _ = 2e5 + 5; int tot, head[_]; struct Edge { int ver, nxt; } edge[_];
inline void Add_edge(int u, int v) { edge[++tot] = (Edge) { v, head[u] }, head[u] = tot; } int n, a[_], dgr[_], rank, ans[_];
priority_queue < int > Q; inline void solve1() {
for (rg int i = 1; i <= n; ++i) if (a[i] != 0) Add_edge(i, a[i]), ++dgr[a[i]];
for (rg int i = 1; i <= n; ++i) if (dgr[i] == 0) Q.push(i);
rank = n;
while (!Q.empty()) {
int u = Q.top(); Q.pop(), ans[u] = rank--;
for (rg int i = head[u]; i; i = edge[i].nxt) if (!--dgr[edge[i].ver]) Q.push(edge[i].ver);
}
for (rg int i = 1; i <= n; ++i) printf("%d%c", ans[i], " \n"[i == n]);
} inline void solve2() {
tot = 0, memset(head, 0, sizeof head);
for (rg int i = 1; i <= n; ++i) if (a[i] != 0) Add_edge(a[i], i), ++dgr[i];
for (rg int i = 1; i <= n; ++i) if (dgr[i] == 0) Q.push(i);
rank = 1;
while (!Q.empty()) {
int u = Q.top(); Q.pop(), ans[u] = rank++;
for (rg int i = head[u]; i; i = edge[i].nxt) if (!--dgr[edge[i].ver]) Q.push(edge[i].ver);
}
for (rg int i = 1; i <= n; ++i) printf("%d%c", ans[i], " \n"[i == n]);
} int main() {
#ifndef ONLINE_JUDGE
file("cpp");
#endif
read(n);
for (rg int i = 1; i <= n; ++i) read(a[i]);
solve1();
solve2();
return 0;
}

「JSOI2010」排名的更多相关文章

  1. 「JSOI2010」挖宝藏

    「JSOI2010」挖宝藏 传送门 由于题目中说道挖一个位置的前提是挖掉它上面的三个,以此类推可以发现,挖掉一个点就需要挖掉这个点往上的整个倒三角,那么也就会映射到 \(x\) 轴上的一段区间(可以发 ...

  2. 「JSOI2010」找零钱的洁癖

    「JSOI2010」找零钱的洁癖 传送门 个人感觉很鬼的一道题... 首先我们观察到不同的数最多 \(50\) 个,于是考虑爆搜. 但是这样显然不太对啊,状态数太多了. 然后便出现了玄学操作: \(\ ...

  3. 「JSOI2010」旅行

    「JSOI2010」旅行 传送门 比较妙的一道 \(\text{DP}\) 题,思维瓶颈应该就是如何确定状态. 首先将边按边权排序. 如果我们用 \(01\) 串来表示 \(m\) 条边是否在路径上, ...

  4. LG4171/BZOJ1823 「JSOI2010」满汉全席 2-SAT

    问题描述 LG4171 BZOJ1823 题解 显然,每个评委对每个材料的满式/汉式要求是对\(n\)个元素的\(0,1\)取值限制. 显然想到\(\mathrm{2-SAT}\) 于是就可以切掉了. ...

  5. 「JSOI2010」满汉全席

    前言 由于蒟蒻才刚开始学 \(\text{2-SAT}\),所以题解中有的地方可能不够精炼,望多包涵! 题目描述 题目意思很简单,标准的\(\text{2-SAT}\)问题模型.那么我们就先来介绍一下 ...

  6. LOJ #6432. 「PKUSC2018」真实排名(组合数)

    题面 LOJ #6432. 「PKUSC2018」真实排名 注意排名的定义 , 分数不小于他的选手数量 !!! 题解 有点坑的细节题 ... 思路很简单 , 把每个数分两种情况讨论一下了 . 假设它为 ...

  7. LibreOJ2241 - 「CQOI2014」排序机械臂

    Portal Description 给出一个\(n(n\leq10^5)\)个数的序列\(\{a_n\}\),对该序列进行\(n\)次操作.若在第\(i\)次操作前第\(i\)小的数在\(p_i\) ...

  8. 「JSOI2014」学生选课

    「JSOI2014」学生选课 传送门 看到这题首先可以二分. 考虑对于当前的 \(mid\) 如何 \(\text{check}\) 我们用 \(f_{i,j}\) 来表示 \(i\) 对 \(j\) ...

  9. iOS 9,为前端世界都带来了些什么?「译」 - 高棋的博客

    2015 年 9 月,Apple 重磅发布了全新的 iPhone 6s/6s Plus.iPad Pro 与全新的操作系统 watchOS 2 与 tvOS 9(是的,这货居然是第 9 版),加上已经 ...

随机推荐

  1. 空字符串(“”)和null和空格字符串(" ")的区别

    1.类型 null表示的是一个对象的值,而并不是一个字符串.例如声明一个对象的引用,String a = null ;""表示的是一个空字符串,也就是说它的长度为0,但它是一个字符 ...

  2. Angular 2.0 文本拖拽

    基于Angular7.1和TypeScript实现 Html代码 <div style="padding-left: 0px;"> <div id='conten ...

  3. Spring-Aop编程(三)-AspectJ

    AspectJ 1. 介绍 AspectJ是一个基于Java语言的AOP框架,Spring2.0以后新增了对AspectJ切点表达式支持,@AspectJ 是AspectJ1.5新增功能,通过JDK5 ...

  4. Docker - 容器的 连接 与 退出

    概述 连接容器, 退出容器 命令 run exec attach 退出 选项 -i -t -d 1. docker run 概述 docker run 通常用来创建新容器 docker run 的 三 ...

  5. LaTeX学习资源

    LaTeX入门 Beamer教程文档 数学公式大全

  6. JS中for循环“全局”变量的传递

    在项目中,遇到了一个问题,描述如下:我们在联动下拉框中,选中值后,会在隐藏的控件中记录一下选中值的主键(展示的是名称).但是,在取消选中的时候,没有把隐藏控件中的value值清空,导致在提交的时候,有 ...

  7. Java开发中模拟接口工具moco的使用

    场景 在开发中需要依赖一些接口,比如需要请求一个返回Json数据的接口,但是返回Json数据的接口要么是没搭建,要么是交互比较复杂. 此时,就可以使用moco来模拟接口返回接口数据,以便开发和测试工作 ...

  8. js中的文本编辑器控件KindEditor

    使用文本编辑器控件KindEditor渲染文本域页面显示 this.sync()同步KindEditor的值到textarea文本框 editor.isEmpty()判断文本域是否是空 editer. ...

  9. BETWEEN

    选取介于两个值之间的数据范围内的值.这些值可以是数值.文本或者日期. 选取 alexa 介于 1 和 20 之间的所有网站: SELECT * FROM table ; NOT BETWEEN 显示不 ...

  10. 树莓派安装ubuntu_meta并配置开发环境

    1.烧录系统 首先准备好我们要烧录的ubuntu_meta系统,可以在树莓派官网中下载https://www.raspberrypi.org/downloads/ 这里我们选择 Raspberry P ...