hdu 6150 Vertex Cover

题目:题目链接在这里

题意:给出一段伪代码,贪心的求最小覆盖点,依次找入度最大的点消除边,但是这个做法存在bug。所以,题目要求就是要你输入一组数据,使得卡掉伪代码的做法,要求就是,使得伪代码的运行结果,是你的标准数据的3倍或者更多。


题解:将这个图建二分图,左边的n个点标号1-n,右边的点的个数至少为3n,这样再建立边的关系,使得贪心的算法的结果是右边的3n,而正确的结果是右边的n个节点。

构图就很重要,因为要使得用贪心的做法求出来的是右边的点,而正解是左边的点集。

将左边的n个点进行i次划分,每次的划分的块数是j,第i次分块中每块的大小为i,然后构造新的右边点,使得这个右边点与左边的划分块里边的每个点相连。(是不是很优秀啊)

①右边的点的度数为n,n-1,n-2,...,n/2,n/2,n/3,n/3,n/3....共有nlogn个点;

②左边的点的度数都不会超过n且只有一个点的度数为n

那么根据贪心算法,会把右边的点都删去,使得输出结果为nlogn,但正确的答案应该是取左边所有的点,只要n取个较大的数就可以使得nlogn>3n即可

(参考大佬的博客:http://blog.csdn.net/qq_31759205/article/details/77417889)

如果涉及任何的侵权,请谅解,这个是写给自己看的,不会去用于任何的商业用途。

参考代码:

#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <queue>
#include <stack>
#include <iostream>
#define pi acos(-1.0)
#define INF 0x3f3f3f3f
using namespace std;
#define ll long long
const int maxn=80;
int  main()
{
    //freopen("C:\\Users\\Administrator\\Desktop\\a.txt","r",stdin);
    //ios::sync_with_stdio(false);
    //freopen("C:\\Users\\Administrator\\Desktop\\b.txt","w",stdout);
    int vertex=80,edge=0;
    printf("368 5234\n");
    for(int i=2;i<=maxn;i++)  //第i次划分
    {
        for(int j=0;j<maxn/i;j++)  //划分的块数
        {
            ++vertex;
            for(int k=1;k<=i;k++)   //每块的大小
                printf("%d %d\n",vertex,i*j+k);
        }
    }
    //cout<<vertex<<" "<<edge<<endl;
    printf("80\n");
    for(int i=1;i<=maxn;i++)
        printf("%d\n",i);
    return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值