loj#2509. 「AHOI / HNOI2018」排列(思维题 set)
题意
Sol
神仙题Orz
首先不难看出如果我们从\(a_i\)向\(i\)连一条边,我们会得到以\(0\)为根的树(因为每个点一定都有一个入度,出现环说明无解),同时在进行排列的时候需要保证父亲节点一定在孩子节点之前出现
接下来考虑直接贪心。对于某些权值很小的点,我们需要让其尽早出现,同时又要满足选择的条件。
那么我们可以从小的点开始,依次向他的父亲合并,并删除该点(也就是如果父亲一但被删除,那么这个点立马被删除)
下面的内容抄袭摘抄自这里

然后直接用set搞一搞
复杂度:\(O(n\log n)\)
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 5e5 + 10, SS = 1e7 + 10;
template<typename A, typename B> inline void chmax(A &x, B y) {
x = x > y ? x : y;
}
inline int read() {
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, a[MAXN], fa[MAXN], vis[MAXN], ufa[MAXN];
LL w[MAXN], siz[MAXN];
vector<int> v[MAXN];
struct comp {
bool operator ()(int x, int y) {
return w[x] * siz[y] == w[y] * siz[x] ? x < y : w[x] * siz[y] < w[y] * siz[x];
}
};
int find(int x) {
return ufa[x] == x ? ufa[x] : ufa[x] = find(ufa[x]);
}
set<int, comp> s;
int dfs(int x) {
vis[x] = 1;
for(auto &to : v[x]) {
if(vis[to] == 1) return 1;
if(dfs(to)) return 1;
}
vis[x] = 2;
return 0;
}
int main() {
N = read();
for(int i = 1; i <= N; i++) {
fa[i] = read();
v[fa[i]].push_back(i);
}
for(int i = 1; i <= N; i++)
if(!vis[i])
if(dfs(i)) {puts("-1"); return 0;}
for(int i = 1; i <= N; i++) w[i] = read(), ufa[i] = i, siz[i] = 1, s.insert(i);
siz[0] = 1; ufa[0] = 0;
LL ans = 0;
for(int i = 1; i <= N; i++) {
int x = *s.begin(); s.erase(s.begin());
int f = find(fa[find(x)]);
if(f) s.erase(f);
ans += siz[f] * w[x];
siz[f] += siz[x]; w[f] += w[x];
ufa[x] = f;
if(f) s.insert(f);
}
cout << ans;
return 0;
}
/*
3
0 1 1
5 7 3
*/
loj#2509. 「AHOI / HNOI2018」排列(思维题 set)的更多相关文章
- loj #2509. 「AHOI / HNOI2018」排列
#2509. 「AHOI / HNOI2018」排列 题目描述 给定 nnn 个整数 a1,a2,…,an(0≤ai≤n),以及 nnn 个整数 w1,w2,…,wn.称 a1,a2,…,an 的 ...
- 【LOJ】#2509. 「AHOI / HNOI2018」排列
题解 虽然要求一个dfs序,但是不是从根开始贪心 从最小的点开始贪心,最小的点显然是父亲选了之后马上就选它 那么我们每次把最小的点和父亲合并,两个联通块之间也是如此 对于两个联通块,他们合并的顺序应该 ...
- Loj #2495. 「AHOI / HNOI2018」转盘
Loj #2495. 「AHOI / HNOI2018」转盘 题目描述 一次小 G 和小 H 原本准备去聚餐,但由于太麻烦了于是题面简化如下: 一个转盘上有摆成一圈的 \(n\) 个物品(编号 \(1 ...
- Loj #2494. 「AHOI / HNOI2018」寻宝游戏
Loj #2494. 「AHOI / HNOI2018」寻宝游戏 题目描述 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得 ...
- loj #2510. 「AHOI / HNOI2018」道路
#2510. 「AHOI / HNOI2018」道路 题目描述 W 国的交通呈一棵树的形状.W 国一共有 n−1 个城市和 nnn 个乡村,其中城市从 111 到 n−1 编号,乡村从 111 到 n ...
- loj #2508. 「AHOI / HNOI2018」游戏
#2508. 「AHOI / HNOI2018」游戏 题目描述 一次小 G 和小 H 在玩寻宝游戏,有 nnn 个房间排成一列,编号为 1,2,…,n,相邻房间之间都有 111 道门.其中一部分门上有 ...
- @loj - 2496@ 「AHOI / HNOI2018」毒瘤
目录 @description@ @solution@ @accepted code@ @details@ @description@ 从前有一名毒瘤. 毒瘤最近发现了量产毒瘤题的奥秘.考虑如下类型的 ...
- loj#2510. 「AHOI / HNOI2018」道路 记忆化,dp
题目链接 https://loj.ac/problem/2510 思路 f[i][a][b]表示到i时,公路个数a,铁路个数b 记忆化 复杂度=状态数=\(nlog^2n\) 代码 #include ...
- loj#2020 「AHOI / HNOI2017」礼物 ntt
loj#2020 「AHOI / HNOI2017」礼物 链接 bzoj没\(letex\),差评 loj luogu 思路 最小化\(\sum\limits_1^n(a_i-b_i)^2\) 设改变 ...
随机推荐
- 【接口时序】2、Verilog实现流水灯及与C语言的对比
一. 软件平台与硬件平台 软件平台: 1.操作系统:Windows-8.1 2.开发套件:ISE14.7 3.仿真工具:ModelSim-10.4-SE 硬件平台: 1.FPGA型号:XC6SLX45 ...
- extern的使用详解(多文件编程)——C语言
extern——关键字 extern是C语言中的一个关键字,一般用在变量名前或函数名前,作用是用来说明“此变量/函数是在别处定义的,要在此处引用”,extern这个关键字大部分读者应该是在变量的存储类 ...
- Redis简明教程
redis是什么: Redis is an open source, BSD licensed, advanced key-value store. It is often referred to a ...
- ubuntu 16.04 安装chrome的方法
默认chrome在ubuntu上是没默认安装,安装也不能使用apt-get 来安装,一般会遇到名字无法找到的问题. 摸索了一下,才找到一个比较好的安装方式: 1 从网站: https://www.ch ...
- Maven - Tips
1- Maven的Settings http://maven.apache.org/settings.html 2- Maven设置代理 示例: <proxies> <proxy&g ...
- ajax无刷新技术
第一步:创建ajax引擎 var xmlhttp=""; if(window.XMLHttpRequest){ xmlhttp=new XMLHttpRequest(); }els ...
- Linux Shell常用shell命令
Linux Shell常用shell命令 一.文件.目录操作命令 1.ls命令 功能:显示文件和目录的信息 ls 以默认方式显示当前目录文件列表 ls -a 显示所有文件包括隐藏文件 ls -l 显示 ...
- Java访问文件夹中文件的递归遍历代码Demo
上代码: import java.io.File; /* * 需求:对指定目录进行所有内容的列出(包含子目录中的内容) * 也可以理解为 深度遍历. */ public class FindAllFi ...
- postgresql 获取修改列的值
使用returning CREATE TABLE users (firstname text, lastname text, id serial primary key); INSERT INTO u ...
- 判断 php 程序是通过什么方式运行的 (浏览器,还是命令行)
php 程序既可以通过浏览器来访问(一般是 apache.nginx等服务器), 也可以通过命令行来直接运行(cli 执行) 如果需要判断 当前程序是以何种方式来执行,应该怎样判断呢,使用:php_s ...