SCU4439-Vertex Cover

针对特定条件下的无向图,提出一种结合暴力搜索与剪枝策略的算法来寻找覆盖所有边所需的最小点集数量。该算法适用于节点数不超过500且每条边至少一端编号小于等于30的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://acm.scu.edu.cn/soj/problem.action?id=4439


题意:n个点,m条边的无向图,n<=500,m<=n*(n-1)/2,对于每条边(u,v),min(u,v)<=30。求最少需要多少个点覆盖所有的边

解题思路:这题的关键点在于min(u,v)<=30。暴搜+剪枝。可以先选一个点,然后搜其他的点,回溯回来后,不选这个点,和它相邻的点都选


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>

using namespace std;

#define LL long long
const int INF=0x3f3f3f3f;

int n,m,ans,tot;
int visit[550];
int p,v;
vector<int>g[550];

void dfs(int k,int sum)
{
    if(sum>ans) return;
    if(k>tot)
    {
        ans=sum;
        return ;
    }
    if(visit[k]) dfs(k+1,sum);
    else
    {
        visit[k]++;
        dfs(k+1,sum+1);
        visit[k]--;
        int Size=g[k].size();
        for(int p=0;p<Size;p++)
        {
            v=g[k][p] ;
            if(!visit[v]) sum++;
            visit[v]++;
        }
        dfs(k+1,sum);
        for(int p=0;p<Size;p++)
        {
            v=g[k][p];
            visit[v]--;
            if(!visit[v]) sum--;
        }
    }
}

int main()
{
    int u, v ;
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1;i<=n;i++) visit[i]=0,g[i].clear();
        ans=INF;
        tot=min(n,30);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&u,&v);
            g[u].push_back(v);
            g[v].push_back(u);
        }
        dfs(1,0);
        printf("%d\n",ans);
    }
    return 0 ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值