这个题容易与战略游戏混起来,战略游戏是每条边的两端点必须有守卫,也就是边的特性,而这题是点的两端必须有守卫,对于战略游戏来说101可以,1001不可以,而1001皇宫这题是可以的,所以我在dp[a]二维数组中加了一个dp[a][2]表示此点不放守卫但是可以以后被父节点表示的情况,还有一个坑点是,dp[a][0]与战略游戏不同,战略游戏dp[a][0]所连的每条边的另一端点都必须有守卫,而皇宫这题则不需要,只需要一个子点有守卫即可,而在遍历的时候会发现,所有子节点的min(dp[son][1],dp[son][0]和已经被统计过,可以直接拿出来用。所以这题就被写出来了。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define INF 9223372036854775807
ll nex[1000001],head[1000001],edge[1000001],val[1000001];
ll dp[5000][3];
ll ans=-1,m;
ll cnt=0;
void dfs(ll a,ll fa)
{
for(ll i=head[a];i;i=nex[i])
{
ll son=edge[i];
if(fa==son) continue;
dfs(son,a);
dp[a][2]+=min(dp[son][1],dp[son][0]);
dp[a][1]+=min(dp[son][1],min(dp[son][0],dp[son][2]));
}
for(ll i=head[a];i;i=nex[i])
{
ll son=edge[i];
if(son==fa) continue;
dp[a][0]=min(dp[a][0],dp[a][2]-min(dp[son][1],dp[son][0])+dp[son][1]);
}
dp[a][1]+=val[a];
}
void add(ll a,ll b)
{
edge[++cnt]=b;
nex[cnt]=head[a];
head[a]=cnt;
}
void solve()
{
ll n,a,b,c;
cin>>n;
for(ll i=1;i<=n;i++)
{
cin>>a;
cin>>val[a];
cin>>m;
for(ll i=1;i<=m;i++)
{
cin>>b;
add(a,b);
add(b,a);
}
}
for(ll i=1;i<=n;i++)
{
dp[i][0]=INF;
}
dfs(1,-1);
if(dp[1][0]==0) cout<<dp[1][1];
else if(dp[1][1]==0) cout<<dp[1][0];
else cout<<min(dp[1][1],dp[1][0]);
}
int main()
{
solve();
return 0;
}