HDUマルチ学校第1001塩辛い魚 - 最小カット+ヒューリスティックモデルマージ

トピックリンク:ポイント私はああ╭(╯^╰)╮

効果の件名:

     n個 n個 の点の根 1 1 ツリーは、各ポイントは、貴重なリンゴの愛
    の木を持っています メートル メートル モニター: バツ バツ K K C C
    地点で バツ バツ 、モニタを有し、それは最短距離で検出することができます K K サブツリー内のすべてのポイントを
    監視する必要の破壊 C C
    最大の収穫を求めて

問題解決のアイデア:

ここに画像を挿入説明
    次の点を説明します。
    各モニタについて、最適な戦略は貪欲の遠い点受け入れるべきトラフィックである
    に挿入される短い長鎖チェーン上の各マージ息子の
    長鎖上の各点に一度挿入され、時間複雑さ: ザ・ n個 O(N)
    各チェーン上の位置で長鎖の中に挿入され、時間の複雑: ザ・ n個 O(N)

コア:最小カットモデリング、長鎖分割の最適化は、合併しました

#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
#define fi first
#define se second
using namespace std;
typedef long long ll;
using pii = pair <int,ll>;
const int maxn = 3e5 + 5;
int T, n, m, f[maxn], a[maxn], dep[maxn];
vector <pii> cam[maxn];
map <int, ll> mp[maxn];

void merge(auto &mp1, auto &mp2){
	if(mp1.size() < mp2.size())
		mp1.swap(mp2);
	for(auto t : mp2) mp1[t.fi] += t.se;
}

int main() {
	scanf("%d", &T);
	while(T--){
		scanf("%d%d", &n, &m);
		for(int i=1; i<=n; i++) mp[i].clear(), cam[i].clear();
		for(int i=2, x; i<=n; i++){
			scanf("%d", &x);
			f[i] = x;
			dep[i] = dep[x] + 1;
		}
		ll ans = 0;
		for(int i=1; i<=n; i++) scanf("%d", a+i), ans += a[i];
		for(int i=1; i<=m; i++){
			int x, k, c;
			scanf("%d%d%d", &x, &k, &c);
			cam[x].push_back({k, c});
		}
		for(int i=n; i; i--){
			mp[i][-dep[i]] += a[i];
			for(auto &u : cam[i]){
				auto it = mp[i].lower_bound(-dep[i] - u.fi);
				while(it != mp[i].end()) {
					if(it->se <= u.se){
						ans -= it->se;
						u.se -= it->se;
						it = mp[i].erase(it);	//	下一个 
					} else {
						ans -= u.se;
						it->se -= u.se;
						u.se = 0;
						break;
					}
				}
			}
			if(f[i]) merge(mp[f[i]], mp[i]);
		}
		printf("%lld\n", ans);
	}
}
公開された221元の記事 ウォンの賞賛220 ・は 20000 +を見て

おすすめ

転載: blog.csdn.net/Scar_Halo/article/details/103019751