最小支配集,求最小的点集覆盖所有的点。
/**
[树形DP] poj 3659 Cell Phone Network
给定一棵树,求最小支配集
dp[i][0] = sum(min(dp[s][2],dp[s][1]))自己没被选,父节点被选中
dp[i][1] = sum(min(dp[s][1],dp[s][2]))自己没被选,某儿子结点被选中
dp[i][2] = sum(min(dp[s][0],dp[s][1],dp[s][2]))自己被选中
求dp[i][1] 时需注意当所有的dp[s][1] < dp[s][2]时是不满足条件的。
*/
#include <stdio.h>
#include <vector>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 10001
#define INF 100000000
vector<int> g[N];
int dp[N][3];
void dfs(int u,int f)
{
dp[u][0] = 0;
dp[u][1] = 0;
dp[u][2] = 1;
if(g[u].size() == 1 && g[u][0] == f)
{
dp[u][1] = INF;
return ;
}
int i,flag = 0,minn = INF,dson = 0,v;
for(i = 0; i < g[u].size(); ++i)
{
v = g[u][i];
if(v == f)
continue;