Test instructions: Finding the smallest dominating set on a tree
Minimum dominating set: The point set, that is, each point can be "dominated" to an adjacent point, and the minimum number of points can be used to control all points.
The minimum dominating set on the graph is NP, but the tree can be done by DP, which is O (n).
It's good to be violent.
F[i] Indicates the minimum cost of full domination of the subtree at the point when it is selected
G[i] Indicates the minimum cost of full domination of the subtree when the parent node is selected
H[i] Indicates the minimum cost of full domination of a subtree when a child node is selected
And then the violence shifts.
(V is a child node)
F[x]=∑ (Min (f[v],min (g[v],h[v))) +1;
G[x]=∑ (min (f[v],h[v]));
H[x]:ⅰ. A f[v]<=h[v]:h[x]=g[x]
Ⅱ. Take one of the least influential f[v], that is, this v has f[v]-h[v] minimum. Other v take min (F[v],h[v]) this is h[v]
Well, this is a normal practice, with a code first:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 10100# Define INF 0x3f3f3f3fusing namespace std;struct ksd{int v,next;} E[n<<1];int head[n],cnt;void Add (int u,int v) {cnt++;e[cnt].v=v;e[cnt].next=head[u];head[u]=cnt;} int n,f[n],g[n],h[n];//Bright, parent bright, child bright void tree_dp (int x,int p) {int i,v,temp=20000;f[x]=1;bool flag=1,flag2=0;for (i=head[x]; I;i=e[i].next) {v=e[i].v;if (v==p) continue; TREE_DP (v,x); F[x]+=min (F[v],min (G[v],h[v])); G[x]+=min (F[v],h[v]); Temp=min (Temp,f[v]-h[v]); if (F[v]<=h[v]) flag2=1;flag=0;} if (flag) H[x]=inf;else {h[x]=g[x];if (!FLAG2) h[x]+=temp;} return;} int main () {//freopen ("test.in", "R", stdin), int i,j,k;int a,b,c;scanf ("%d", &n), for (i=1;i<n;i++) {scanf ("%d%d" , &a,&b), add (A, B), add (B,a);} TREE_DP (1,0);p rintf ("%d\n", Min (f[1],h[1])); return 0;}
And a long time ago to write greed:
#include <stdio.h> #include <string.h> #include <stdlib.h> #define N 10100typedef struct Ksd{int v,next ;} KSD;KSD e[2*n];int head[n],n,ans;int attack[n],killed[n];void Add (int note,int U,int v) {E[note].v=v;e[note].next=head [U];head[u]=note;} void Init () {Ans=0;memset (head,-1,sizeof (head)); Memset (attack,0,sizeof (Attack)); Memset (Killed,0,sizeof (killed));} void Dfs (int x,int p) {int i,j,k,t,v;for (t=head[x];t!=-1;t=e[t].next) {if (e[t].v!=p) DFS (e[t].v,x);} if (killed[x]==0) {ans++;attack[p]=killed[x]=killed[p]=1;for (t=head[p];t!=-1;t=e[t].next) {killed[e[t].v]=1;}}} int main () {//freopen ("test.in", "R", stdin), int i,j,k;int a,b,c;while (scanf ("%d", &n)!=eof) {init (); for (i=1;i< n;i++) {scanf ("%d%d", &a,&b); add (i*2-1,a,b); add (i*2,b,a);} DFS (1,0);p rintf ("%d\n", ans);} return 0;
"POJ3659" "Usaco-Jan Gold" 3.Cell Phone Network tree Minimum domination set/greedy two practices