Portal: QAQQAQ
Meaning of the questions: placed in a tree guarding, so that each node has at least placed adjacent to a node guarding a final minimum funding
Ideas: tree DP
First, think of no party boss, 0 and hold the guards, 1 put guards, but given the current point guard will hold two situations:
1. His father put a guard, the guard put his son is not necessary
2. His father did not put a guard, then his son must have at least put a guard
So the idea is quite clear: dp1 indicates the current discharge point guard, dp0 not represent the current point guard, his father guarded, dp2 not represent the current guard, his father did not guard, and then to recursive
Read in point may be of the order, which needs attention.
Code:
#include<bits/stdc++.h> #define ll long long using namespace std; const ll N=1020+500; const ll inf=2000000000; ll n,w[N],dp[N][3];//0:father1now0 1:now1 2:father0now0 vector<ll> v[N]; ll checkmin(ll x,ll y,ll z) { return min(min(x,y),z); } void dfs(ll u,ll f) { ll bl=0,minn=inf; for(ll i=0;i<(ll)v[u].size();i++) { ll p=v[u][i]; if(p==f) continue; dfs(p,u); dp[u][1]+=min(dp[p][1],dp[p][0]); dp[u][0]+=min(dp[p][2],dp[p][1]); if(dp[p][1]<=dp[p][2]) { bl=1; dp[u][2]+=dp[p][1]; } else { dp[u][2]+=dp[p][2]; minn=min(minn,dp[p][1]-dp[p][2]); } } dp[u][1]+=w[u]; if(!bl) dp[u][2]+=minn; } int main() { scanf("%lld",&n); for(ll i=1;i<=n;i++) { ll tmp,m; scanf("%lld",&tmp); scanf("%lld%lld",&w[tmp],&m); for(ll j=1;j<=m;j++) { ll x; scanf("%lld",&x); v[tmp].push_back(x); v[x].push_back(tmp); } } memset(dp,0,sizeof(dp)); dfs(1,-1); printf("%lld",min(dp[1][1],dp[1][2])); return 0; }