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;
}