题意:给定一棵树,要选取最少的节点 使与 被选取的节点 相连的所有边 能够覆盖整棵树。
思路:DP,f[i][0]表示在不选取i号节点的情况下至少选多少个节点才能覆盖以i号节点为根的子树,f[i][1]表示在 选取 i号节点的情况下至少选多少个节点才能覆盖以i号节点为根的子树。
转移方程:f[i][0]=∑f[son[i]][0],f[i][1]=∑min(f[son[i]][0],f[son[i]][1]);
没什么细节。
1 #include<iostream> 2 #include<cstring> 3 #include<string> 4 #include<cstdio> 5 #include<cstdlib> 6 #include<cmath> 7 #include<algorithm> 8 #include<queue> 9 #include<stack> 10 #include<set> 11 #include<map> 12 #include<vector> 13 #define ll long long 14 #define ull unsigned long long 15 using namespace std; 16 const int MAXN = 1505; 17 inline int read() 18 { 19 int x=0;char c=getchar(); 20 for (;!isdigit(c);c=getchar()); 21 for (;isdigit(c);c=getchar()) x=x*10+c-'0'; 22 return x; 23 } 24 25 inline void write(int x) 26 { 27 register int bit[20],i,p=0; 28 if (x==0) {putchar('0');return;} 29 for (;x;x/=10) bit[++p]=x%10; 30 for (i=p;i>0;--i) putchar(bit[i]+48); 31 } 32 int f[MAXN][2],bj[MAXN],n; 33 struct node{ 34 int next,v; 35 }e[MAXN*2];int num=0,head[MAXN]; 36 inline void add(int u,int v){ 37 e[++num].next=head[u]; 38 e[num].v=v; 39 head[u]=num; 40 } 41 void dfs(int x,int fa){ 42 if(bj[x])return; 43 for(int i=head[x];i;i=e[i].next){ 44 if(e[i].v==fa)continue; 45 dfs(e[i].v,x); 46 f[x][0]+=f[e[i].v][1]; 47 f[x][1]+=min(f[e[i].v][0],f[e[i].v][1]); 48 } 49 } 50 int main() 51 { 52 cin>>n; 53 for(int i=0;i<n;i++)f[i][1]=1; 54 for(int i=1;i<=n;i++){ 55 int x=read(),k=read();if(k==0)bj[x]=1; 56 for(int j=1;j<=k;j++){ 57 int y=read();add(x,y),add(y,x); 58 } 59 }dfs(0,-1); 60 cout<<min(f[0][0],f[0][1]); 61 return 0; 62 }
浙公网安备 33010602011771号