Luo Gu P2016 strategy game

Luo Gu P2016 strategy game

Description

  • Bob likes to play computer games, especially strategy game. But he often could not find a way to quickly played the game. Now he has a problem.

    He wants to establish an ancient castle, the castle road form a tree. He is to be placed on the minimum number of tree nodes soldiers so that soldiers can beheld all the way.

    Note that, when a soldier on a node, all the edges connected to the node can be a glancing.

    You compile a program that, given a tree to help Bob to calculate the minimum he needs to place soldiers.

Input

  • The first line N, the number of nodes in the tree.

    The second row to row 1 + N, with each line describing information of each node, as follows: the reference node I, k (k edges behind connected to node I).

    Next number k, respectively, of another node of each edge numeral r1, r2, ..., rk.

    For a n (0 <n <= 1500) of the tree nodes, the node numbers between 0 and n-1, appears once every edge in the input data only.

Output

  • The output file contains only a number, minimum number of soldiers is asked for.

Sample Input

4
0 1 1
1 2 2 3
2 0
3 0

Sample Output

1

answer:

  • Excerpt from pengym greatly

  • In fact, there are several ways this question, perhaps one of the more obvious tree dp bar, downstairs there are a lot of heavyweights already explained, (here

    Do not say that again), a closer look at this question can be found on a typical minimum point coverage . Minimum Vertex Cover refers in one figure: a point

    Side covers attached thereto, can find a point with a minimum coverage. This is exactly the same questions asked. As well as a theorem, Minimum Vertex Cover =

    The maximum number of matches. If it is undirected graph / 2. Therefore, it is easy to think of playing the Hungarian algorithm.

#include <iostream>
#include <cstdio>
#include <cstring>
#define N 1505
using namespace std;

struct E {int next, to;} e[N * N * 2];
int n, num, ans;
int h[N], mat[N];
bool vis[N];

int read()
{
    int x = 0; char c = getchar();
    while(c < '0' || c > '9') c = getchar();
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
    return x;
}

void add(int u, int v)
{
    e[++num].next = h[u];
    e[num].to = v;
    h[u] = num;
}

bool dfs(int x)
{
    for(int i = h[x]; i != 0; i = e[i].next)
        if(!vis[e[i].to])
        {
            vis[e[i].to] = 1;
            if(!mat[e[i].to] || dfs(mat[e[i].to]))
            {
                mat[e[i].to] = x;
                return 1;
            }
        }
    return 0;
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        int u = read() + 1, k = read();
        for(int i = 1; i <= k; i++)
        {
            int v = read() + 1;
            add(u, v), add(v, u);
        }
    }
    for(int i = 1; i <= n; i++)
    {
        memset(vis, 0, sizeof(vis));
        if(dfs(i)) ans++;
    }
    cout << ans / 2;
    return 0;
}

Guess you like

Origin www.cnblogs.com/BigYellowDog/p/11583852.html