建议听一下QQ音乐的Lost Rivers体会楼主心情。 50分↓
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int k=0;bool f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=0;ch=getchar();}
while(isdigit(ch)){k=(k<<1)+(k<<3)+(ch^48);ch=getchar();}
return f?k:~k+1;
}
const int N=1502;
struct Edge{
int to,next;
}e[N];
int h[N],tot;
inline void Addage(int u,int v){
e[++tot].to=v;
e[tot].next=h[u];
h[u]=tot;
}
int n,w[N],f[N][3];
//f[x][0]记录能让x被覆盖的时候子树全覆盖的最小花费
//f[x][1]记录当x节点自身有保安的时候子树全覆盖的最小花费
//f[x][2]记录让x的所有子节点的子树被覆盖时的最小花费
void DP(int x){
int p=e[h[x]].to;
f[x][1]=w[x];
if(h[x]==0) {
f[x][0]=w[x];
return ;
}
for(int i=h[x];i;i=e[i].next)
{
DP(e[i].to);
f[x][1]+=f[e[i].to][2];
f[x][2]+=f[e[i].to][0];
if(f[e[i].to][1]-f[e[i].to][0]<f[p][1]-f[p][0])
p=e[i].to;
}
for(int i=h[x];i;i=e[i].next)
if(e[i].to!=p) f[x][0]+=f[e[i].to][0];
else f[x][0]+=f[e[i].to][1];
f[x][0]=min(f[x][0],f[x][1]);
}
bool vis[N];
int main(){
n=read();
for(int i=1;i<=n;i++)
{
int x=read();
w[x]=read();
int s=read();
for(int j=1;j<=s;j++)
{
int y=read();vis[y]=1;
Addage(x,y);
}
}
int root;
for(int i=1;i<=n;i++)
if(!vis[i]) root=i;
DP(root);
printf("%d",f[root][0]);
return 0;
}