Dmy_树上路径2

#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = (a); i <= (b); i ++ )
using namespace std;
using LL = long long;
template <typename T> void chkmax(T &x, T y) { x = max(x, y); }
template <typename T> void chkmin(T &x, T y) { x = min(x, y); }

constexpr int N = 2010;
constexpr LL INF = 1LL << 60;

int n, m, fa[N], dep[N];
vector<int> edge[N];
vector<array<int, 2> > path[N];

LL dp[N][N];

void merge(LL *a, LL *b, int len) {
	static LL sufa[N], sufb[N];
	sufa[len + 1] = INF;
	sufb[len + 1] = INF;

	for(int i = len; i >= 1; i -- ) {
		sufa[i] = min(sufa[i + 1], a[i]);
		sufb[i] = min(sufb[i + 1], b[i]);
	}

	for(int i = 1; i <= len; i ++ ) {
		a[i] = min(a[i] + sufb[i], b[i] + sufa[i]);
	}
	/*
	for(int i = 1; i <= len; i ++ )
		for(int j = 1; j <= len; j ++ ) {
			a[i] + b[j] --> tmp[min(i, j)];
		}
	*/
} 

void dfs(int u) {
	for(int i = 1; i <= dep[u]; i ++ ) dp[u][i] = INF;

	for(auto &[v, w]: path[u]) {
		chkmin(dp[u][dep[v]], (LL)w);
	}
	//dp[u][dep[u] + 1] = 0;
	for(int &v: edge[u]) {
		dfs(v);
		/* 暴力合并
		for(int i = 1; i <= n; i ++ )
			for(int j = 1; j <= dep[v]; j ++ ) 
				chkmin(tmp[min(i, j)], dp[u][i] + dp[v][j])
		*/
		merge(dp[u], dp[v], dep[v]); 
		//合并的时候至少要把 v 点 覆盖掉
	}
}

int main() {
	#ifndef ONLINE_JUDGE
 		freopen("1.txt", "r", stdin);
 		freopen("2.txt", "w", stdout);
 	#endif
	
	scanf("%d%d", &n, &m);

	dep[1] = 1;
	for(int i = 2; i <= n; i ++ ) {
		scanf("%d", &fa[i]);
		edge[fa[i]].push_back(i);
		dep[i] = dep[fa[i]] + 1;
	} 

	for(int i = 0; i < m; i ++ ) {
		int u, v, w;
		scanf("%d%d%d", &u, &v, &w);
		path[v].push_back({u, w});
	}
	dfs(1);
	LL ans = dp[1][1];
	if(ans >= INF) puts("-1");
	else printf("%lld\n", ans);

    return 0;

}
posted @   ccz9729  阅读(54)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
主题色彩