Strategic game POJ - 1463 树形DP
题目链接:POJ - 1463
题目大意:给你一个无向图,然后每个点都会被标记的点直接相邻,并切被标记的点大于等于1的前提下,最少需要对几个点进行染色。
具体思路:
dp[i][0] 代表标号为I的点在不染色的前提下,这个点代表的子树符合条件最少需要对这个点的几个点进行染色。
dp[i][1] 代表标号为i的点在染色的前提下,这个点代表的子树符合条件最少需要对这个点的子树中的几个点进行染色。
do[i][0] = dp[i][0] + dp[to][1].
dp[i][1] = dp[i][1] + min(dp[to][0],dp[to][1]).
AC代码:
1 #include<iostream>
2 #include<stdio.h>
3 #include<cmath>
4 #include<algorithm>
5 #include<vector>
6 using namespace std;
7 # define ll long long
8 # define inf 0x3f3f3f3f
9 const int maxn = 2e5+100;
10 vector<int>Edge[maxn];
11 int dp[maxn][2],vis[maxn];
12 int ans;
13 void dfs(int u)
14 {
15 vis[u]=1;
16 for(int i=0; i<Edge[u].size(); i++)
17 {
18 int to=Edge[u][i];
19 if(vis[to])
20 continue;
21 dfs(to);
22 dp[u][1]+=min(dp[to][0],dp[to][1]);
23 dp[u][0]+=dp[to][1];
24 }
25 }
26 int main()
27 {
28 int n;
29 while(~scanf("%d",&n))
30 {
31 int st,num,ed;
32 ans=0;
33 char u;
34 for(int i=0; i<=n; i++)
35 {
36 Edge[i].clear();
37 dp[i][0]=0;
38 dp[i][1]=1;
39 vis[i]=0;
40 }
41 for(int i=0; i<n; i++)
42 {
43 scanf("%d:(%d)",&st,&num);
44 for(int j=1; j<=num; j++)
45 {
46 scanf("%d",&ed);
47 Edge[st].push_back(ed);
48 Edge[ed].push_back(st);
49 }
50 }
51 dfs(0);
52 printf("%d\n",min(dp[0][1],dp[0][0]));
53 }
54 return 0;
55 }