poj 1419

题目大意:
给一个无向图,要求给每个点染色,每两个黑色点之间不能有边,白色点可以。求最大黑色点数及染色方案。
这道题就是求此图的最大独立集,也就是求其补图的最大团。
**何为最大独立集呢(⊙o⊙)?
从图中选取n个点,这n个点之间任意两点之间没有边相连,就是此图的一个独立集。
**那么最大团呢(⊙o⊙)?
从图中选取n个点,这n个点之间任意两点之间有边相连,就是此图的一个团。
那么显然图的最大独立集就是其补图的最大团
如何求最大团
born-kerbosch算法告诉你
首先,朴素的STMD算法出场^_^

//伪代码
dfs(y--已取的点的集合,l待处理的点的集合,n--不取的点的集合){
    //nn--n集合的size,其他同nn
    if(nn==0&&ln==0)
        y已经是最大团,returnfor(l中的每个点v){
        dfs(y∪{v},l∩N(v),n∩N(v));
        //N(v)为顶点v相邻的点。
        l=l除去v;
        n=n加入v;
    }
}       

详细代码>o<

void dfs(int d, int ny, int nl, int nn)
//d为搜索深度
{
    if(nl == 0 && nn == 0) //nl==0搜索到终点,只有nn==0时,才是一个最大团
    for(int i = 1; i <=nl; i ++)
    {
        int v = l[d][i];
        int tnl= 0, tnn = 0;
        for(int j = 1; j < =an; j ++) y[d + 1][j] = y[d][j];
        y[d + 1][ny] = v;
        for(int j = 1; j < =nl; j ++)if(g[v][l[d][j]]) l[d + 1][tnl ++] = l[d][j];
        for(int j = 1; j < =nn; j ++) if(g[v][n[d][j]]) n[d + 1][tnn ++] = n[d][j];
        dfs(d + 1, ny + 1, tnl, tnn);
        //把v从y取出,放入n
        l[d][i] = 0, n[d][nn ++] = v;
    }
}

但是>o<这种算法太朴素了,我们还是剪一剪枝为好
对于任意的最大团,其必须包括顶点v或者v的非邻接点.否则就可以添加顶点v来扩充极大团.所以.我们只要测试 顶点v以及 v的非邻接点即可.这样可以节省递归的时间.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值