题解:P12734 理解
ELECTRODE_kaf · · 题解
每个时间最多只有一个前置事件,那么事件之间的关系可以看做一个森林。题目所求的方案就是这个森林的一个子图,按照回想每个子树的根节点,再沿着树边联想的方式遍历每个关键点。代价就是选中的子图中包含的每个子树的根节点的点权和加上边权和。
还需考虑题中关于脑容量的额外限制。记脑容量为
考虑 DP。设
若不选节点
同理联想其它事件时当前事件肯定还在占用脑容量,所以脑容量为
const ll N=1e5+10,K=20,MAX=1e17;
ll n,m,k;
vector<ll> g[N];
ll r[N],t[N];
bool tg[N];
ll dp[N][K],l[N][K];
ll min3(ll a,ll b,ll c){
return min(min(a,b),c);
}
void ini(){
init(tg,0);
init(dp,0);
init(l,0);
rep(i,0,N-1) g[i].clear();
}
void solve(){
cin>>n>>m>>k;
rep(i,1,n){
ll p;
cin>>p;
g[p].pb(i);
}
// rep(i,0,n){
// cout<<i<<':';
//
// for(ll j:g[i]) cout<<j<<' ';
//
// endl;
// }
//
// pause;
rep(i,1,n) cin>>r[i];
rep(i,1,n) cin>>t[i];
rep(i,1,m){
ll p;
cin>>p;
tg[p]=1;
dp[p][0]=MAX;
}
rep_(i,n,1){
if(g[i].empty()) ctn;
for(ll j:g[i]){
ll f1,f2;
rep(u,2,k){
f1=min3(dp[j][0],dp[j][k]+r[j],dp[j][u-1]+t[j]);
dp[i][u]+=f1;
f2=dp[j][u]+t[j];
update(l[i][u],f1-f2,max);
}
dp[i][1]+=min(dp[j][0],dp[j][k]+r[j]);
// cout<<"signal 1\ndp[i][1]="<<dp[i][1]<<'\n';
// cout<<dp[j][0]<<' '<<dp[j][k]+r[j]<<'\n';
// pause;
}
rep(j,2,k){
dp[i][j]-=l[i][j];
update(dp[i][j],dp[i][j-1],min);
}
if(tg[i]==0) dp[i][0]=dp[i][1];
// rep(j,0,k){
// cout<<"dp["<<i<<"]["<<j<<"]="<<dp[i][j]<<'\n';
// pause;
// }
}
ll ans=0;
for(ll i:g[0]) ans+=min(dp[i][0],dp[i][k]+r[i]);
cout<<ans<<'\n';
}
int main(){
ll Q;
cin>>Q;
count(Q){
ini();
solve();
}
}