題目大意
給一棵樹, 在節點上放一個士兵, 可以把與節點相連的邊都監測到, 求把所有的邊都監測到所放的最少的士兵
樣例
Sample Input
4
0:(1) 1
1:(2) 2 3
2:(0)
3:(0)
5
3:(3) 1 4 2
1:(1) 0
2:(0)
0:(0)
4:(0)
Sample Output
1
2
思路
代碼
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int N = 1510;
int ne[N], h[N], e[N], len;
int n;
bool vis[N];
int f[N][2];
void add(int a, int b)
{
e[len] = b;
ne[len] = h[a];
h[a] = len++;
}
void dfs(int x)
{
vis[x] = true;
f[x][1] = 1;
f[x][0] = 0;
for(int i = h[x]; ~i; i = ne[i])
{
int y = e[i];
if(vis[y]) continue;
dfs(y);
f[x][0] += f[y][1];
f[x][1] += min(f[y][0], f[y][1]);
}
}
int main()
{
while(scanf("%d", &n) == 1)
{
memset(h, -1, sizeof h);
memset(vis, false, sizeof vis);
memset(f, 0, sizeof f);
len = 0;
for(int i = 0; i < n; i++)
{
int a, cnt;
scanf("%d:(%d)", &a, &cnt);
for(int j = 1; j <= cnt; j++)
{
int b;
cin >> b;
add(a, b);
vis[b] = true;
}
}
int root;
for(int i = 0; i < n; i++)
if(!vis[i])
{
root = i;
break;
}
memset(vis, 0, sizeof vis);
dfs(root);
cout << min(f[root][0], f[root][1]) << endl;
}
return 0;
}