SCU4439-Vertex Cover

来源:互联网 发布:东莞网站建设优化技术 编辑:程序博客网 时间:2024/06/13 19:25

题目链接: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 longconst 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 ;}

0 0
原创粉丝点击