题解:
基础树形dp
dp[u][0] 表示不选u.那么子节点v都要选
dp[u][1]表示选择u,那么子节点v可选可不选
代码:
#include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define pii pair<int,int> #define ll long long const int maxn = 1600; int dp[ maxn ][ 2 ]; int n; int head[ maxn * 2 ], cnt; struct Edge { int u, v, nxt; }edge[ maxn * 2 ]; void addedge( int u, int v ) { edge[ cnt ].u = u; edge[ cnt ].v = v; edge[ cnt ].nxt = head[ u ]; head[ u ] = cnt ++; } void init() { cnt = 0; memset( head, -1, sizeof( head ) ); } void dfs( int u, int fa ) { dp[ u ][ 1 ] = 1; dp[ u ][ 0 ] = 0; for( int i = head[ u ]; i != -1; i = edge[ i ].nxt ) { int v = edge[ i ].v; if( v == fa ) continue; dfs( v, u ); dp[ u ][ 1 ] += min( dp[ v ][ 1 ], dp[ v ][ 0 ] ); dp[ u ][ 0 ] += dp[ v ][ 1 ]; } } int main() { while( ~scanf( "%d", &n ) ) { init(); while( n ) { int u, v, num; scanf( "%d:(%d)", &u, &num ); for( int i = 1; i <= num; i ++ ) { scanf( "%d", &v ); addedge( u, v ); addedge( v, u ); } n --; } dfs( 0, -1 ); printf( "%d\n", min( dp[ 0 ][ 0 ], dp[ 0 ][ 1 ] ) ); } return 0; }
时间: 2024-11-12 14:42:44