题解:POI2012 Salaries

Description

The Byteotian Software Corporation (BSC) has \(n\) employees.

In BSC's strict hierarchy, each employee has a direct supervisor, except the CEO, to whom all other BSC employees answer, directly or not.

Each employee has a unique monthly salary, and all their salaries range from 1 to \(n\) bythalers.

Each supervisor earns more than each of their subordinates.

According to Byteotian law, the salaries of employees on certain posts may be publicly disclosed.

Furthermore, if the salary of an employee is disclosed, then the salary of their supervisor is also disclosed.

The Byteotian Internal Revenue Anti-Corruption Service (BIRAS) has decided to investigate BSC.

Before BIRAS enters BSC with a warrant, they intend to learn the salaries of all BSC employees that are not disclosed but can be determined from those that are disclosed.

题意:

给一棵 \(n\) 个结点的树,点权取 \(1 \sim n\) 且 各不相同。

满足任意非根结点的权值一定比它的父节点权值小。

现在自顶向下地已知一些点的权值(即若某非根点权值已知,其父节点的权值也一定已知),

问哪些点的权值能唯一确定。

\(n \leq 1e6\)

Algorithm

这是一道 十分有趣 而 一言难尽 的题目。

我们先从两个例子入手,试图理解一下「唯一确定」的意思。

例一

在这里,由于点 \(b\) 是点 \(3\) 的孙子结点,最大只能取 \(1\) ,因此唯一确定 \(b = 1\)

同时,点 \(a\) 是点 \(3\) 的儿子结点,可能的取值有 \(1, 2\) ,但因为 \(b = 1\) ,所以唯一确定 \(a = 2\)

例二

此处 \(a, b\) 都是 \(3\) 的子节点,他们的取值可能为 \(1, 2\) ,但并不能唯一确定一种对应关系。

\(c\) 是 \(5\) 的子节点,可能的取值有 \(1, 2, 4\) 。但因为 \(a, b\) 对应 \(1, 2\) ,只能有 \(c = 4\) ,这也是唯一确定的。

揆诸上例与题面自顶向下给权的性质,我们容易发现:

  1. 对于任意一个未确定的结点,它的可能取值范围总是 \((0,x_i]\) ,

    其中, \(x_i\) 是由树的结构与已知点权共同决定的。

  2. 一个点的权能被唯一确定,当且仅当其取值范围为 \((x_i - 1, x_i]\)

  3. 当我们确定了 \(k\) 个结点的取值后,剩余的未确定结点的取值范围就会变化为 \((k, x_i]\)

  4. 确定点权的顺序总是从小到大的。

(写成左开右闭的形式仅仅是为了规避区间左右端点相等的写法,没别的意思)

接下来只要模拟上述的推理即可。

我们可以首先一次 DFS 遍历整棵树,根据树结构维护每个点可能的最大取值。

特别注意此处有个坑,如果仅根据点的祖先结点取值和深度计算 \(x_i\) 的话代码就是错误的。

经过这种方法计算出的值 \(x'_i\) 可能已经被某个已知点取了,你需要尝试不断减少 \(x'_i\) 的值直到其符合定义为止。

这个"不断减少"的过程可以预处理出来。

DFS 之后,我们可以根据最大取值将点排序,再依次考虑每个权是否可以被确定或唯一确定。

这个算法描述起来还挺模糊的……不如直接读代码:

#include<bits/stdc++.h>
using namespace std; template<class T>
inline void read(T &x)
{
char c = getchar(); x = 0;
while(c < '0' || '9' < c) c = getchar();
while('0' <= c && c <= '9')
{
x = (x << 1) + (x << 3) + c - 48;
c = getchar();
}
} const int INF = 0x7f7f7f7f;
typedef pair<int, int> Node;
vector<Node> ord; template<const int N, const int M>
class Tree {
private:
int beg[N], nex[M], tar[M], len;
public:
int vap[N], van[N];
bool vis[N]; Tree():len(1) {}
inline void add_egde(int a, int b)
{
++len, tar[len] = b;
nex[len] = beg[a], beg[a] = len;
} void dfs(int cur, int val)
{
if(!vap[cur]) ord.push_back(Node(val, cur));
for(int i = beg[cur]; i; i = nex[i])
{
if(vap[tar[i]]) dfs(tar[i], vap[tar[i]]);
else dfs(tar[i], van[val - 1]);
}
}
}; Tree<1048576, 1048576> T;
int main()
{
int n, rot; read(n);
for(int i = 1, x; i <= n; ++i)
{
read(x), read(T.vap[i]); if(x == i) rot = i, T.vap[i] = n;
else T.add_egde(x, i); if(T.vap[i])
T.vis[T.vap[i]] = true;
} for(int i = 1; i <= n; ++i)
{
if(T.vis[i]) T.van[i] = T.van[i - 1];
else T.van[i] = i;
} T.dfs(rot, n);
sort(ord.begin(), ord.end()); int done = 0, len = ord.size();
for(int i = 1, j = 0; i <= n; i++)
{
if(T.vis[i]) done++;
else
{
int cnt = 0;
while(j < len && ord[j].first == i) j++, cnt++;
if(cnt == 1 && done == i - 1)
T.vap[ord[j - 1].second] = i;
done += cnt;
}
} for(int i = 1; i <= n; ++i)
printf("%d\n", T.vap[i]); return 0;
}

题解:POI2012 Salaries的更多相关文章

  1. 【BZOJ2799】[Poi2012]Salaries 乱搞

    [BZOJ2799][Poi2012]Salaries Description 给出一棵n个结点的有根树,结点用正整数1~n编号.每个结点有一个1~n的正整数权值,不同结点的权值不相同,并且一个结点的 ...

  2. [BZOJ2799][Poi2012]Salaries

    2799: [Poi2012]Salaries Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 91  Solved: 54[Submit][Statu ...

  3. [POI2012]Salaries

    题目大意: 给定一棵n带权树,每个点的权值在[1,n]范围内且互不相等,并满足子结点的权值一定小于父结点. 现在已知一个包含根结点的联通块中个点的权值,求剩下哪些点的权值能够被求出,并求出这些权值. ...

  4. bzoj 2799 [Poi2012]Salaries 性质+二分

    题目大意 给出一棵n个结点的有根树,结点用正整数1~n编号. 每个结点有一个1~n的正整数权值,不同结点的权值不相同, 并且一个结点的权值一定比它父结点的权值小(根结点的权值最大,一定是n). 现在有 ...

  5. POI2012题解

    POI2012题解 这次的完整的\(17\)道题哟. [BZOJ2788][Poi2012]Festival 很显然可以差分约束建图.这里问的是变量最多有多少种不同的取值. 我们知道,在同一个强连通分 ...

  6. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  7. [Poi2012]Festival 题解

    [Poi2012]Festival 时间限制: 1 Sec  内存限制: 64 MB 题目描述 有n个正整数X1,X2,...,Xn,再给出m1+m2个限制条件,限制分为两类: 1. 给出a,b (1 ...

  8. 【题解】 [POI2012]FES-Festival (差分约束)

    懒得复制题面,戳我戳我 Question: (因为网上找不到好的翻译,这里简单复述一下) 告诉你\(m1+m2\)个约束条件,然后要你找出\(X_1-X_n\)这些数字,求满足要求的数列中不同的数字个 ...

  9. BZOJ2802: [Poi2012]Warehouse Store

    2802: [Poi2012]Warehouse Store Time Limit: 10 Sec  Memory Limit: 64 MBSec  Special JudgeSubmit: 121  ...

随机推荐

  1. 解锁用户scott并授权

    请输入用户名: system 输入口令: 连接到: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Producti ...

  2. Nginx 路由--Location的使用

    一. 路由--Location的使用 9.1. Location语法规则 语法规则: location [=|~|~*|^~] /uri/ {… } 首先匹配 =,其次匹配^~,其次是按文件中顺序的正 ...

  3. Tomcat源码分析(类加载与类加载器)

    Tomcat的挑战 Tomcat上可以部署多个项目 Tomcat的一般部署,可以通过多种方式启动一个Tomcat部署多个项目,那么Tomcat在设计时会遇到什么挑战呢? Tomcat运行时需要加载哪些 ...

  4. Httprunner框架学习

    前言 HttpRunner 是一款面向 HTTP(S) 协议的通用测试框架,只需编写维护一份 YAML/JSON 脚本,即可实现自动化测试. 官方文档:https://docs.httprunner. ...

  5. [LeetCode]11. 盛最多水的容器(双指针)

    题目 给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0).找出其中的两 ...

  6. 分布式系统监视zabbix讲解七之分布式监控

    分布式监控 概述 Zabbix通过Zabbix proxy为IT基础设施提供有效和可用的分布式监控 代理(proxy)可用于代替Zabbix server本地收集数据,然后将数据报告给服务器. Pro ...

  7. JsonPath使用教程

    application/json标识Json数据格式,是Http请求常见的一种Content-Type.我们经常也会看到接口返回数据类型为json格式.功能测试/自动化脚本里,经常会需要提取json数 ...

  8. v-charts 绘制柱状图、条形图、水球图、雷达图、折线图+柱状图,附官网地址

    v-charts 官网地址:https://v-charts.js.org/#/ 柱状图: <template> <ve-histogram :data="chartDat ...

  9. vue单页面条件下添加类似浏览器的标签页切换功能

    在用vue开发的时候,单页面应用程序,而又有标签页这种需求,各种方式实现不了, 从这个 到这个,然后再返回上面那个 因为每个标签页的route不一样,导致组件重新渲染的问题,怎么都不知道如何实现... ...

  10. python第一节课内容及练习

    一.input输入 sname = input("请输入你的姓名:")yu_yan = input("请输入你学习的语言:")print("{}, 欢 ...