bzoj2806 [Apio2012]dispatching可并堆

Posted ciao_sora

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj2806 [Apio2012]dispatching可并堆相关的知识,希望对你有一定的参考价值。

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2809

保存可并堆模版代码。

#include <cstdio>
#include <cstring>
#include <algorithm>

const int maxn = 100005, maxm = 1000000005;

int n, m, fa[maxn], salary[maxn], lead[maxn];
int key[maxn], left[maxn], right[maxn], npl[maxn], cnt, siz[maxn];
int head[maxn], to[maxn], next[maxn], lb;
long long s[maxn], ans;

inline void ist(int aa, int ss) {
	to[lb] = ss;
	next[lb] = head[aa];
	head[aa] = lb;
	++lb;
}
int merge(int A, int B) {
	if (!A) {
		return B;
	}
	if (!B) {
		return A;
	}
	if (key[B] > key[A]) {
		std::swap(A, B);
	}
	right[A] = merge(right[A], B);
	if (npl[right[A]] > npl[left[A]]) {
		std::swap(left[A], right[A]);
	}
	npl[A] = npl[right[A]] + 1;
	s[A] = s[left[A]] + s[right[A]] + key[A];
	siz[A] = siz[left[A]] + siz[right[A]] + 1;
	return A;
}
int dfs(int r) {
	int rt = ++cnt, tr = -666;
	key[rt] = salary[r];
	s[rt] = salary[r];
	siz[rt] = 1;
	for (int j = head[r]; j != -1; j = next[j]) {
		tr = dfs(to[j]);
		rt = merge(rt, tr);
	}
	while (s[rt] > m) {
		rt = merge(left[rt], right[rt]);
	}
	ans = std::max(ans, (long long)lead[r] * (long long)siz[rt]);
	return rt;
}

int main(void) {
	//freopen("in.txt", "r", stdin);
	memset(head, -1, sizeof head);
	memset(next, -1, sizeof next);
	npl[0] = -1;
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; ++i) {
		scanf("%d%d%d", fa + i, salary + i, lead + i);
		ist(fa[i], i);
	}
	
	dfs(1);
	printf("%lld\n", ans);
	return 0;
}

  

以上是关于bzoj2806 [Apio2012]dispatching可并堆的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ2809 [Apio2012]dispatching

APIO2012BZOJ2809派遣dispatching

BZOJ2809: [Apio2012]dispatching

BZOJ 28092809: [Apio2012]dispatching (左偏树)

Bzoj2809 [Apio2012]dispatching

BZOJ2809APIO2012dispatching