树的最小支配集:
定义1 对于图G=(V,E)来说,最小支配集指的是从V中取尽量少的点组成一个集合,使得对于V中剩余的点都与取出来的点有边相连。也就是说,设V‘是图G的一个支配集,则对于图中的任意一个顶点u,要么属于集合V’,要么与V‘中的顶点相邻。在V’中出去任何元素后V‘不再是支配集,则支配集是极小支配集。称G的所有支配集中顶点个数最少的支配集为最小支配集,最小支配集中顶点的个数称为支配数。
注意这里只是实现部分,要如何使用要根据题目而变。
const inf=999999999;
int dp[250][3]; //0表示选中此点的父亲,1表示选中此点,2表示选中此点的儿子
vector<int>vec[250]; //这个下标i是父亲结点,vec[i]向量保存儿子结点
void MDS_DP(int u,int fa)
{
dp[u][0]=0;
dp[u][1]=1;
int inc=inf;
int sum=0;
bool mark=false;//表示还没选好儿子
for(int i=0;i<vec[u].size();++i)
{
int j=vec[u][i];
if(j==fa) continue; //这句话以防万一,题目中儿子结点恰是自己的父亲,使一直循环下去
MDS_DP(j,u);
if(dp[j][1]<=dp[j][2])
{
mark=true; //找到了某个儿子,他选自己比不选自己要使用更少(或相同)的节点数。
sum+=dp[j][1]; //加上这个选中自己的结点。
}
else
{
sum+=dp[j][2];
inc=min(inc,dp[j][1]-dp[j][2]); //以防没找到理想的孩子,就要使一个孩子受最小的损失,来满足他父亲的愿望。
}
}
if(mark==true)
{
dp[u][2]=sum;
}
else
{
if(vec[u].size()==0)
dp[u][2]=inf;
else
dp[u][2]=inc+sum; //真没找到合适的孩子,便要在理想的基础上,加上最小的代价。
}
}
树的最大独立集:
定义3 对于图G=(V,E)来说,最大独立集指的是从V中取尽量多的点组成一个集合,使得这些点之间没有边相连。也就是说,设V’是图G的一个独立集,则对于图中任意一条边(u,v),u和v不能同时属于集合V',甚至可以u和v都不属于集合V‘。在V’中添加任何不属于V‘元素后V’不再是独立集,则V‘是极大独立集。称G的所有顶点独立集中顶点个数最多的独立集为最大独立集。
这里也只是实现。
vector<int>vec[250];
int dp[250][2],n; //0表示不选此点,1表示选此点
void dfs(int v,int p)
{
vec[v][0]=0;
vec[v][1]=1;
for(int i=0;i<vec[v].size();++i)
{
int sz=vec[i].size();
int u=vec[v][i];
if(u==p) continue; //与上相同
dfs(u,v);
dp[i][0]+=max(dp[u][0],dp[u][1]); // 如果没选此点,则它的儿子可选,可不选。
dp[i][1]+=dp[u][0]; // 若是选了,儿子不能选。
}
}