Los establish Valley P2279 [HNOI2003] fire station

The meaning of problems

Given a tree, it can be covered with a fire station from his point of less than 2.

How many fire stations seek to cover the entire tree needs.

analysis

There are greedy thoughts and ideas moving regulation, this problem solution using the dynamic regulation.

Therefore, according to the conventional DP routine of a tree, we state a subtree divided state as a standard. However, a subtree may also cover may point out, there may be several points uncovered.

Since the coverage radius is 2, divided by 5 for a sub-tree states:

\ (f_ {i, 0} \) cover 2 upwardly.

\ (f_ {i, 1} \) covers up a.

\ (f_ {i, 2} \) just finished covering subtree.

\ (f_ {i, 3} \) End cover son.

\ (f_ {i, 4} \) End cover grandchildren.

The number of fire stations needed.


\ (f_ {i, 0} \) chose himself, it will be overwritten to grandchildren. Great-grandson all requirements are covered, son 0-4 state meet.

\[f_{i,0}=1+\min(f_{i.child,[0,4]})\]

\ (f_ {i, 1} \) is selected from one of the son node, the other sons will be covered. But the other son's son can not be covered. Therefore, when the transfer, fire station randomly selected a discharge point, and other points in claim son is covered.

\[f_{i,1}=\min(\min (f_{i.child,[0,3]})_{i.child!=k}+f_{k,0} )_{k\in \{i.child\}}\]

Similarly there

\[f_{i,2}=\min(\min (f_{i.child,[0,2]})_{i.child!=k}+f_{k,1} )_{k\in \{i.child\}}\]

Let the son of the root is covered, it is to let themselves are covered (good zz ah)

\[f_{i,3}=\sum(f_{i.child,[0,2]})\]

Similarly there

\[f_{i,4}=\sum(f_{i.child,[0,3]})\]

accelerate

Takes the minimum value [0,2], that is, when the answer to the cover itself.

For state 0, [0,4] and most obviously 4

\[f_{i,0}=1+\min(f_{i.child,4})\]

Similarly there

\[f_{i,3}=\sum(f_{i.child,2})\]

\[f_{i,4}=\sum(f_{i.child,3})\]

The status 0,3 and 4 is completed, they can be used to optimize the transfer 1 and 2.

State 1, all grandchildren can be covered, then take \ (f_ {i.child, 0} {i.child, 3} \ -f_) minimum. This equation is equivalent to the number of fire station coverage desired point adjacent to i.

So have

\[f_{i,1}=\min (f_{i.child,0}-f_{i.child,3})+f_{i,4}\]

Similarly there

\[f_{i,2}=\min (f_{i.child,2}-f_{i.child,1})+f_{i,3}\]

Finally, you'll find useful or greedy

(

Code

Do not look, ugly, or copied.

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=1005;
int n,ne,head[MAXN],cnt,temp,temp1,temp2;
int f[MAXN][5];
bool tree[MAXN][MAXN];

int main()
{
    scanf("%d",&n);
    
    for(int i=2;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        tree[x][i]=1;
    }
    for(int i=n;i>=1;i--)
    {
        f[i][0]=1;
        temp1=1919,temp2=1919;
        for(int p=1;p<=n;p++)
        {
            if(tree[i][p])
            {
                f[i][3]+=f[p][2];
                f[i][4]+=f[p][3];
                f[i][0]+=f[p][4];
                temp1=min(temp1,f[p][0]-f[p][3]);
                temp2=min(temp2,f[p][1]-f[p][2]);
            }
        }
        f[i][1]=f[i][4]+temp1;
        f[i][2]=min(f[i][3]+temp2,min(f[i][0],f[i][1]));
        f[i][3]=min(f[i][2],f[i][3]);
        f[i][4]=min(f[i][4],f[i][3]);;
    }
    printf("%d",f[1][2]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/ehznehc/p/11372148.html