Topic Link: Click to open the link
Title Description: Given a tree, choose as few points as possible so that each point is either selected or connected directly to the selected point.
The idea of solving a problem: the minimum dominating set on a tree, the tree DP
DP[I][0]: Select I as the dominating set
DP[I][1]: Do not select I as the dominant set, but its child nodes cover I
DP[I][2]: Do not select I as the dominant set, and its child nodes do not cover I
Code:
#pragma COMMENT (linker, "/stack:1024000000,1024000000") #include <cstdio> #include <cstring> #include < iostream> #define MAXN 10010#define INF 1e9+7using namespace std;int head[maxn],tol;struct edge{int v,next;} Edge[maxn*2];void Addedge (int u,int v) {edge[tol].v=v;edge[tol].next=head[u];head[u]=tol++; edge[tol].v=u;edge[tol].next=head[v];head[v]=tol++;} int min (int a,int b) {return a<b?a:b;} int Dp[maxn][3];int n;void dp (int u,int p) {dp[u][2]=0; Dp[u][0]=1; int sum=0,inc=inf; int k,to; BOOL S=false; for (K=head[u];k!=-1;k=edge[k].next) {to=edge[k].v; if (to==p) continue; DP (To,u); Dp[u][0]+=min (Dp[to][0],min (dp[to][1],dp[to][2)); if (Dp[to][0]<=dp[to][1]) {sum+=dp[to][0]; S=true; } else {sum+=dp[to][1]; Inc=min (inc,dp[to][0]-dp[to][1]); } if (Dp[to][1]!=inf&&dp[u][2]!=inf) dp[u][2]+=dp[to][1]; else Dp[u][2]=inf; } if (inc==inf&&!s) Dp[u][1]=inf; else{dp[u][1]=sum; if (!s) dp[u][1]+=inc; }}int Main () {while (scanf ("%d", &n)!=eof) {Tol=0;memset (head,-1,sizeof (head)); int u,v; for (int i=0;i<n-1;++i) {scanf ("%d%d", &u,&v); Addedge (u,v);} DP (+); printf ("%d\n", Min (min (dp[1][0],dp[1][1)), dp[1][2]+1)); } return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
poj3659 Cell Phone Network (minimum domination set-tree DP)