关闭

点支配、点覆盖、点独立

298人阅读 评论(0) 收藏 举报
分类:

【概念】

(1)点支配集,极小点支配集,最小点支配集,点支配数----γ0(G);

(2)点覆盖集,极小点覆盖集,最小点覆盖集,点覆盖数----α0(G);

(3)点独立集,极大点独立集,最大点独立集,点独立数----β0(G);

(4)边覆盖集,极小边覆盖集,最小边覆盖集,边覆盖数----α1(G);

(5)边独立集,及答辩独立集,最大边独立集,边独立数----β1(G);

对于无向图来说,且没有孤立顶点:

α0(G)+β0(G) = n;

α1(G)+β1(G) = n;

对于二部图来说,(无向二部图G有n个顶点,且没有孤立顶点):

α0(G) = β1(G) ;

β0(G) = n - β1(G);

说明:如果二部图有m个孤立顶点,则β0(G) 和n中分别扣除m个孤立顶点后满足该式,即:β0(G) -m = n-m-β1(G)。这样原式:β0(G) = n - β1(G),仍然成立。

----------------------------------------------------------------------------------------------------------------------------

【支配与支配集】

设无向图为G(V,E),顶点集合V*属于V,若对于任意v∈(V-V*),存在一个u∈V*,使得(u,v)∈E,则称u支配v,并称V*为G的一个点支配集。

通俗的讲,V-V*中的每个顶点都是V*中某个顶点的邻接顶点,或者说V中的顶点要么是V*集合中的元素,要么与V*中的一个顶点相邻。

极小支配集:若支配集V*的任何真子集都不是支配集,则称V*是极小支配集。

最小支配集:顶点数最少的支配集称为最小支配集。

点支配数:最小支配集中的顶点数称为点支配数。

点支配集的性质

性质1:若G中无孤立顶点,则存在一个支配集V*,使得G中除V*外的所有顶点也组成一个支配集。

性质2:若G中无孤立顶点,V*为极小支配集,则G中除V*外的所有顶点也组成一个支配集。

POJ 3659

基本算法:

以最小支配集为例,首先选择一点为根,按照深度优先遍历得到遍历序列,按照所得序列的反向序列的顺序进行贪心,对于一个既不属于支配集也不与支配集中的点相连的点来说,如果他的父节点不属于支配集,将其父节点加入支配集。

#include <iostream>
#include <algorithm>
#include <string.h>
#include <stdio.h>
using namespace std;
const int N = 1e5+10;
struct Edge{
    int v,next;
}G[N];
int fa[N];
int vis[N];
int pos[N],head[N],top;
int now,n;
int s[N];
int set[N];
void init(){
    now = 0,top = 0;
    memset(vis,0,sizeof(vis));
    memset(head,-1,sizeof(head));
    memset(s,0,sizeof(s));
    memset(set,0,sizeof(set));
}
void DFS(int u){
    pos[now++] = u;
    for(int i = head[u]; ~i; i=G[i].next){
        int v = G[i].v;
        if(!vis[v]){
            vis[v] = 1;
            fa[v] = u;
            DFS(v);
        }
    }
}
void add(int u,int v){
    G[top] = {v,head[u]};
    head[u] = top++;
}
int MDS(){
    int ans = 0;
    for(int i = now-1; i >= 0; --i){
        int t = pos[i];
        if(!s[t]){
            if(!set[fa[t]]){
                set[fa[t]] = 1;
                ans++;
            }
            s[t] = 1;
            s[fa[t]] = 1;
            s[fa[fa[t]]] = 1;
        }
    }
    return ans;
}
int main(){
    int u,v;
    while(~scanf("%d",&n)){
        init();
        for(int i = 0; i < n-1; ++i){
            scanf("%d%d",&u,&v);
            add(u,v),add(v,u);
        }
        DFS(1);
        int ans = MDS();
        cout<<ans<<endl;
    } 
    return 0;
}

【点覆盖】

点覆盖集V*,就是G中所有的边至少有一个顶点属于V*。

极小点覆盖:若点覆盖V*的任何真子集都不是点覆盖,则称V*是极小点覆盖。

最小点覆盖:顶点个数最少的点覆盖称为最小点覆盖。

点覆盖数:最小点覆盖的顶点数称为点覆盖数。

求点覆盖数。

int MPC()
{
    int s[N] = {0};
    int set[N] = {0};
    int ans = 0;
    for(int i=now-1;i>=0;i--)
    {
        int t = pos[i];
        if(!s[t] && !s[fa[t]])
        {
            set[fa[t]] = 1;
            ans++;
            s[t] = 1;
            s[fa[t]] = 1;
        }
    }
    return ans;
}

【点独立】

点独立集:设无向图为G(V,E),顶点集合V*属于V,若V*中任意两个顶点都均不相邻,则称V*为G的点独立集。

极大点独立集:若在V*中加入任何顶点都不再是独立集,则称V*为极大点独立集。

最大点独立集:顶点数最多的点独立集称为最大点独立集。

点独立数:最大点独立集的顶点数称为点独立数。

点独立数

int MIS()
{
    int s[N] = {0};
    int set[N] = {0};
    int ans = 0;
    for(int i=now-1;i>=0;i--)
    {
        int t = pos[i];
        if(!s[t])
        {
            set[t] = 1;
            ans++;
            s[t] = 1;
            s[fa[t]] = 1;
        }
    }
    return ans;
}

点支配集、点覆盖集、点独立集之间的联系

定理 1 设无向图G(V,E)中无独立顶点,则G的极大点独立集都是G的极小支配集。逆命题不成立(即极小支配集未必是极大独立集).

定理 2 一个独立集是极大独立集,当且仅当它是一个支配集。

定理 3 设无向图G(V,E)中无独立顶点,则V*是G的极小(最小)点覆盖集,当且仅当V-V*是G的极大(最大)点独立集,从而有:点覆盖+点独立=n(n为顶点个数)。



0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:14078次
    • 积分:1171
    • 等级:
    • 排名:千里之外
    • 原创:107篇
    • 转载:8篇
    • 译文:0篇
    • 评论:0条