5289: [Hnoi2018]排列
5289: [Hnoi2018]排列
分析:
首先将题意转化一下:每个点向a[i]连一条边,构成了一个以0为根节点的树,要求选一个拓扑序,点x是拓扑序中的第i个,那么价值是i*w[x]。让价值最大。
然后贪心:直观的考虑,应该让权值小的尽量靠前,那么依次考虑当前最小的权值,一旦选了它的父节点,那么下一个就会选它。将它和父节点合并,新的权值为平均数,并且记录下siz。推广一下即每次选平均数最小的集合,和父节点所在的集合合并。
证明:如果当前有两个集合x,y,如果x在前面更优,那么$w[x] + w[y] \times siz[x] > w[y] + w[x] \times siz[y]$
$w[x] \times (siz[y] - 1) < w[y] \times (siz[x] - 1 ) $
$\frac{w[x]}{siz[x] - 1} < \frac{w[y]}{siz[y] - 1}$
所以x在y前面的条件是平均数小,那么就可以用堆来维护了。注意一下如果平均数比较的话,要开long double,或者直接按照上面的第二个式子来比较,不存在精度问题。
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} #define pa pair<long double,int>
const int N = ;
int fa[N], a[N], siz[N];
LL w[N]; struct Heap{
priority_queue< pa, vector< pa >, greater< pa > > a, b;
void Insert(pa x) { a.push(x); }
void Delete(pa x) { b.push(x); }
pa Top() {
while (!b.empty() && a.top() == b.top()) a.pop(), b.pop();
return a.top();
}
}q;
int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
int main() {
int n = read();
for (int i = ; i <= n; ++i) fa[i] = i;
for (int i = ; i <= n; ++i) {
a[i] = read();
int u = find(a[i]), v = find(i);
if (u != v) fa[u] = v;
else { puts("-1"); return ; }
}
LL ans = ;
for (int i = ; i <= n; ++i) fa[i] = i;
for (int i = ; i <= n; ++i) {
w[i] = read(); siz[i] = ; ans += w[i];
q.Insert(pa(w[i], i));
}
for (int k = ; k <= n; ++k) {
pa now = q.Top(); q.Delete(now);
int x = now.second, y = find(a[x]);
if (y) q.Delete(pa((long double)w[y] / siz[y], y));
ans += 1ll * siz[y] * w[x];
w[y] += w[x]; siz[y] += siz[x]; fa[x] = y;
if (y) q.Insert(pa((long double)w[y] / siz[y], y));
}
cout << ans;
return ;
}
5289: [Hnoi2018]排列的更多相关文章
- bzoj 5289: [Hnoi2018]排列
Description Solution 首先注意到实际上约束关系构成了一棵树 考虑这个排列 \(p\),编号为 \(a[i]\) 的出现了,\(i\) 才可以出现 那么如果连边 \((a[i],i) ...
- 【BZOJ5289】[HNOI2018]排列(贪心)
[BZOJ5289][HNOI2018]排列(贪心) 题面 BZOJ 洛谷 题解 这个限制看起来不知道在干什么,其实就是找到所有排列\(p\)中,\(p_k=x\),那么\(k<j\),其中\( ...
- BZOJ.5289.[AHOI/HNOI2018]排列(贪心 heap)
BZOJ LOJ 洛谷 \(Kelin\)写的挺清楚的... 要求如果\(a_{p_j}=p_k\),\(k\lt j\),可以理解为\(k\)要在\(j\)之前选. 那么对于给定的\(a_j=k\) ...
- [HNOI2018]排列
Description: 给定 \(n\) 个整数 \(a_1, a_2, \dots, a_n, 0 \le a_i \le n\),以及 \(n\) 个整数 \(w_1, w_2, \dots, ...
- [HNOI2018]排列[堆]
题意 给定一棵树,每个点有点权,第 \(i\) 个点被删除的代价为 \(w_{p[i]}\times i\) ,问最小代价是多少. 分析 与国王游戏一题类似. 容易发现权值最小的点在其父亲选择后就会立 ...
- BZOJ5289: [Hnoi2018]排列
传送门 第一步转化,令 \(q[p[i]]=i\),那么题目变成: 有一些 \(q[a[i]]<q[i]\) 的限制,\(q\) 必须为排列,求 \(max(\sum_{i=1}^{n}w[i] ...
- BZOJ5289:[HNOI2018]排列
我对贪心的理解:https://www.cnblogs.com/AKMer/p/9776293.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem ...
- loj2509 hnoi2018排列
题意:对于a数组,求它的一个合法排列的最大权值.合法排列:对于任意j,k,如果a[p[j]]=p[k],那么k<j. 权值:sigma(a[p[i]]*i).n<=50W. 标程: #in ...
- 【比赛】HNOI2018 排列
这题原题... 这题题面七绕八绕,有点麻烦,反正最后转化就是一棵树,每个点有一个值,要把所有点选完,要求选择一个点必须是它的父亲和祖先已经全部被选了,贡献是这个点的权值乘上它被选择的排名 如果一个点是 ...
随机推荐
- 数据库启动丢失MSVCP120.dll
在自己第一次安装数据库的时候发生了很多问题,,首当其冲的就是数据库启动时丢失MSVCP120.dll,这里就不配图了(安装好了才想起来写一篇博客). 为什么安装不了? 这是因为系统缺失必要的运行库导致 ...
- Ubuntu下安装指定版本的mysql
1.编辑/etc/apt/sources.list和/etc/apt/sources.list.save, 手动加上deb http://archive.ubuntu.com/ubuntu trust ...
- git did not exit cleanly (exit code 128)
github,pull和push的时候出问题,提示git did not exit cleanly (exit code 128) 使用HTTP格式的url,不要使用SSH格式的url,在官网上赋值下 ...
- Eclipse Debug Daemon Thread
Daemon Thread ["http-bio-8080"-exec-2] (Suspended (exception RuntimeException)) ThreadPool ...
- c++ thread 使用不当导致的崩溃问题
看个例子 class CTimer{ public: // 析构函数 virtual ~CTimer(){ } // 开始 void start() { b_exit = false; i = ; t ...
- Leetcode Weekly Contest 86
Weekly Contest 86 A:840. 矩阵中的幻方 3 x 3 的幻方是一个填充有从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等. 给定一个 ...
- 1483. [HNOI2009]梦幻布丁【平衡树-splay】
Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色. 例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input ...
- P1710 地铁涨价
题目背景 本题开O2优化,请注意常数 题目描述 博艾市除了有海底高铁连接中国大陆.台湾与日本,市区里也有很成熟的轨道交通系统.我们可以认为博艾地铁系统是一个无向连通图.博艾有N个地铁站,同时有M小段地 ...
- 20155314 2016-2017-2 《Java程序设计》第3周学习总结
20155314 2016-2017-2 <Java程序设计>第3周学习总结 教材学习内容总结 学习目标 区分基本类型与类类型 理解对象的生成与引用的关系 掌握String类和数组 理解封 ...
- 简单说说Vue
Vue.js是这次我们公司迭代项目使用的前端框架之一.我们前端使用的是一个叫Metronic的.Metronic的可以说是bootstrap系列的集合. 当然也用到一个叫layui的,layui的话就 ...