P2899 [USACO08JAN] phone network Cell Phone Network

Meaning of the questions:

A n points are not entitled to the tree, for the most coverage of small dots

 

Ideas:

So, we consider a node can be dyed by whom, is not difficult to come up with, there may be three cases: dyed myself, being the son of dyeing, dyed his father

We wish to set up:

f [i] [0] represents f [i] own dyeing [1] on behalf of his father dyed f [i] [2] represents staining son

Set the current node is u, v is the son node

Let's consider the transfer equation:

1 I have been dyeing their own

Then we can think about, u by their own staining can be transferred from what is to come, if u have dyed his words, his son v You can choose your own coloring, you can also choose to be their own stained son, of course, can also be u staining of course, we want to choose the smallest, so that the transfer equation

f [u] [0] + = min (f [v] [0], f [v] [1], f [v] [2])

 

2 by their own father node staining

If the father node ( f A) staining, then u son of v can only choose their own stained or dyed by its son, the transfer equation

f[u][1] += min(f[v][1],f[v][0] )

 

 

3 by his own son nodes stained

This is the most troublesome case, because u may have more sons, a son of their own as long as there is a stain, it can u cover, this situation is set up

And now it's the son of two cases, which are themselves dyeing and staining it was his son

We can assume that each son is dyed (its own v is its own dyed), and then look at the u of each son ( v) whether his son is dyed to make the results become smaller, to make the results less their staining ( replacing his own son v staining) is dyed their son son ( v dyed its son) son

 

 

 

#include <iostream>
#include <algorithm>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <math.h>
#include <cstdio>
#include <iomanip>
#include <time.h>
#include <bitset>
#include <cmath>

#define LL long long
#define INF 0x3f3f3f3f
#define ls nod<<1
#define rs (nod<<1)+1

const double eps = 1e-10;
const int maxn = 1e5 + 10;
const LL mod = 1e9 + 7;

int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;}
using namespace std;

struct edge {
    int v,nxt;
}e[maxn << 1];

int head[maxn];
int cnt;
int f[maxn][3];


inline void add_edge(int u,int v) {
    e [ ++ cnt] .v = v;
    to [cnt] .nxt = Head [e];
    head[u] = cnt;
}

void dfs(int u,int fa) {
    f[u][0] = 1;
    int tot = 0;
    int g[maxn];
    for (int i = head[u];~i;i = e[i].nxt) {
        int v = e[i].v;
        if (v == fa)
            continue;
        dfs (v, u);
        f [u] [ 0 ] + = min (f [v] [ 0 ] [min (f [v] [ 1 ], f [v] [ 2 ]));
        f[u][1] += min(f[v][0],f[v][2]);
        f[u][2] += f[v][0];
        g [ ++ tot] = f [v] [ 2 ] - f [v] [ 0 ];
    }
    if (!tot)
        f[u][2] = INF;
    else {
        sort(g+1,g+1+tot);
        for (int i = 1;i < tot;i++) {
            if (g[i] < 0)
                f[u][2] += g[i];
            else
                break;
        }
    }
}


int main () {
    cnt = 0;
    memset(head,-1, sizeof(head));
    int n;
    cin >> n;
    for (int i = 1;i < n;i++) {
        int u,v;
        cin >> u >> v;
        add_edge(u,v);
        add_edge(v,u);
    }
    dfs(1,0);
    cout << min(f[1][0],f[1][2]) << endl;
    return 0;
}

 

 

Guess you like

Origin www.cnblogs.com/-Ackerman/p/12339750.html