HDU 6150 Vertex Cover【构造二分图】

本文介绍了一种构造特殊图的方法,旨在挑战一种近似顶点覆盖算法。通过构建特殊的二分图,使该近似算法选取的顶点数量远超理想情况。文章详细阐述了构建思路与算法实现。

source:

2017中国大学生程序设计竞赛 - 网络选拔赛


题意:这是2017中国大学生程序设计竞赛网络选拔赛的题1。首先题目给你一个求最小顶点覆盖的近似算法:每次取度数最大的点删去它和其关联的所有边,继续该过程直到完成覆盖。现要求构造一个图来“卡”这个算法,就是说要构造一个足够“坏”的图,使得按照题目该出的近似算法求出的顶点覆盖集的规模>=你能给出的顶点覆盖规模。输出构造的图和给出你的顶点覆盖。

思路:

    看到此题时以为只用在演算纸上画出符合条件的图,然后程序直接输出,而事实证明并没这么简单,还是需要运用步骤性的算法解决。其实首先可以这样思考,假如我的顶点覆盖方案有n个点,那么要让近似算法选3*n个点,不妨直接构造成二分图,左边n个点,右边3n个点,现在目的便是连边使得近似算法取右边作为顶点覆盖即可。

    连边的话倒着来想即可,右边取到最后只剩一个点(不妨设为n+1号点)时,要保证取n+1号点,那么该点至少连一条边到左边点集即可,这里要注意一点:留意近似算法是度数相同时取编号大的,所以预留的1~n号为自个儿方案的点就是这个目的。好继续倒推,对于n+2号点也只需连一条边到左边点集,不与刚刚n+1号点连的相同即可,依次类推一直到2n号点都只需连一条线,而对于2n+1号点,由于左边点集现在都已经度数为1了,所以2n+1号点至少要连两条边,这样这三个点都是度数为2,优先取2n+1满足条件,如此思路倒推回去....右边点集可以构造出来的点数:度数为1的有n个点,度数为2点的n/2,n/3,n/4.... n/k   求和只要大于3n即可

    我取n=50大概算了一下,k=12即可。

代码如下:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;


int main()
{
    int n=50; //n为二分图左边的点数+3n为二分图右边点数
    int tot=0,m=0,weight=1;
    for(int i=n+1;i<=4*n;i++)
    {
        m+=weight;
        tot+=weight;
        if(tot+weight>n)
        {
            weight++;
            tot=0;
        }
    }//以上统计边数m
    printf("%d %d\n",4*n,m);
    weight=1;
    tot=0;
    for(int i=n+1;i<=4*n;i++)
    {
        for(int j=tot+1;j<=tot+weight;j++)
        {
            printf("%d %d\n",j,i);
            m++;
        }
        tot+=weight;
        if(tot+weight>n)
        {
            weight++;
            tot=0;
        }
    }
    printf("%d\n",n);
    for(int i=1;i<=n;i++) printf("%d\n",i);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值