Tarjan + 树形DP 40pts 求条
查看原帖
Tarjan + 树形DP 40pts 求条
957799
xuanxiao2024楼主2025/7/18 23:10
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
struct node{
	ll w,v;
};
ll n,m,top,cnt,id;
ll dfn[105],low[105],s[105],scc[105];
ll Size[105],dp[105][505];
bool vis[105];
node a[105],b[105];
vector<ll> G[105],g[105];

void dfs(ll x){
	vis[x] = 1;
	s[++top] = x;
	dfn[x] = low[x] = ++id;
	for(auto nx:G[x]){
		if(dfn[nx] == 0){
			dfs(nx);
			low[x] = min(low[x],low[nx]);
		}else if(vis[nx] == 1){
			low[x] = min(low[x],dfn[nx]);
		}
	}
	if(dfn[x] == low[x]){
		cnt++;
		while(s[top] != x){
			vis[s[top]] = 0;
			scc[s[top]] = cnt;
			b[cnt].w += a[s[top]].w;
			b[cnt].v += a[s[top]].v;
			top--;
		}
		vis[s[top]] = 0;
		scc[s[top]] = cnt;
		b[cnt].w += a[s[top]].w;
		b[cnt].v += a[s[top]].v;
		top--;
	}
	return ;
}

void DFS(ll x,ll fa){
	// cout << x << "\n";
	Size[x] = b[x].w;
	for(int i = 0;i < b[x].w;i++) dp[x][i] = -1e9;
	for(int i = b[x].w;i <= m;i++) dp[x][i] = b[x].v;
	for(auto nx:g[x]){
		if(nx != fa){
			DFS(nx,x);
			Size[x] += Size[nx];  
			for(int i = min(Size[x],m);i >= 0;i--){
				for(int j = 0;j <= min(Size[nx],i * 1ll);j++){
					dp[x][i] = max(dp[x][i],dp[x][i - j] + dp[nx][j]);
				}
			}
		}
	}
	return ;
}

int main(){
	cin >> n >> m;
	for(int i = 1;i <= n;i++){
		cin >> a[i].w;
	}
	for(int i = 1;i <= n;i++){
		cin >> a[i].v;
	}
	for(int s = 1;s <= n;s++){
		ll e;
		cin >> e;
		G[e].push_back(s);
	}
	for(int i = 0;i <= n;i++){
		if(dfn[i] == 0){
			dfs(i);
		}
	}
	for(int x = 0;x <= n;x++){
		for(auto nx:G[x]){
			if(scc[x] != scc[nx]){
				g[scc[x]].push_back(scc[nx]);
			}
		}
	}
	DFS(scc[0],0);
	// for(int i = 0;i <= n;i++){
	// 	cout << scc[i] << " ";
	// 	for(int j = 0;j <= m;j++){
	// 		cout << dp[scc[i]][j] << " ";
	// 	}
	// 	cout << "\n";
	// }
	cout << dp[scc[0]][m];
	return 0;
}

本人刚学习 OI 三个月,麻烦巨佬帮忙调一下!

感谢各位巨佬的帮忙!!!

2025/7/18 23:10
加载中...