scu 4439 Vertex Cover(暴搜+剪枝)
2015-06-17 20:13
387 查看
题目链接
She would like to color some vertices so that each edge has at least one colored vertex.
Find the minimum number of colored vertices.
The first line contains 2 integers n,m (2≤n≤500,1≤m≤n(n−1)2). Each of the following m lines contains 2 integers ai,bi (1≤ai,bi≤n,ai≠bi,min{ai,bi}≤30)
题意:n个点,m条边的无向图,n<=500,m<=n*(n-1)/2,对于每条边(u,v),min(u,v)<=30。求最少需要多少个点覆盖所有的边。
题解:求一般图的最小顶点覆盖,是NPC问题,所以这题只有搜了。这题的关键点在于min(u,v)<=30。我们可以搜索前30个点的状态,在加上剪枝解决此题。
具体搜索方法如下:
只搜索前30个点的选与不选,如果还有边没有被覆盖则一定选非前30的点来覆盖。这样一定可以搜索到最优解。
如果一个点不选则起相邻的点必选。
所以我们初始化所有的点都选,然后搜索哪些点不选。
当我们搜索到一个点的时候,判断它相邻的点是否有不选的,若有则必选;否则我们可以选择不选该点。这样搜索出来的状态对于前30个点之间的边来说一定是合法的。再加上最优性剪枝就可过这题。
代码如下:
采用Bitset的代码如下:
Vertex Cover
frog has a graph with n vertices v(1),v(2),…,v(n) and m edges (v(a1),v(b1)),(v(a2),v(b2)),…,(v(am),v(bm)).She would like to color some vertices so that each edge has at least one colored vertex.
Find the minimum number of colored vertices.
Input
The input consists of multiple tests. For each test:The first line contains 2 integers n,m (2≤n≤500,1≤m≤n(n−1)2). Each of the following m lines contains 2 integers ai,bi (1≤ai,bi≤n,ai≠bi,min{ai,bi}≤30)
Output
For each test, write 1 integer which denotes the minimum number of colored vertices.Sample Input
3 2 1 2 1 3 6 5 1 2 1 3 1 4 2 5 2 6
Sample Output
1 2
题意:n个点,m条边的无向图,n<=500,m<=n*(n-1)/2,对于每条边(u,v),min(u,v)<=30。求最少需要多少个点覆盖所有的边。
题解:求一般图的最小顶点覆盖,是NPC问题,所以这题只有搜了。这题的关键点在于min(u,v)<=30。我们可以搜索前30个点的状态,在加上剪枝解决此题。
具体搜索方法如下:
只搜索前30个点的选与不选,如果还有边没有被覆盖则一定选非前30的点来覆盖。这样一定可以搜索到最优解。
如果一个点不选则起相邻的点必选。
所以我们初始化所有的点都选,然后搜索哪些点不选。
当我们搜索到一个点的时候,判断它相邻的点是否有不选的,若有则必选;否则我们可以选择不选该点。这样搜索出来的状态对于前30个点之间的边来说一定是合法的。再加上最优性剪枝就可过这题。
代码如下:
#include<stdio.h> #include<iostream> #include<algorithm> #include<math.h> #include<string.h> #include<queue> #include<list> using namespace std; typedef long long LL; const int nn = 550; const int inf = 0x3fffffff; const int mod = 10000003; int n,m; struct node { int en,next; }E[nn*nn*2]; int p[nn],num; void init() { memset(p,-1,sizeof(p)); num=0; } void add(int st,int en) { E[num].en=en; E[num].next=p[st]; p[st]=num++; E[num].en=st; E[num].next=p[en]; p[en]=num++; } pair<int,int>a[35]; bool use[35]; bool tu[35][35]; int N; int ans; int du[nn]; int fg; int fuck[nn]; void dfs(int id,int val) { if(val+fg>=ans) return ; if(id==N+1) { ans=min(ans,val+fg); return ; } bool ok=true; int i,w; for(i=1;i<=N;i++) { if(tu[id][i]&&use[i]) { ok=false; } } if(ok) { use[id]=true; for(i=p[id];i+1;i=E[i].next) { w=E[i].en; if(fuck[w]==0) { fg++; } fuck[w]++; } dfs(id+1,val); for(i=p[id];i+1;i=E[i].next) { w=E[i].en; fuck[w]--; if(fuck[w]==0) { fg--; } } use[id]=false; } dfs(id+1,val+1); } int main() { int i,u,v; while(scanf("%d%d",&n,&m)!=EOF) { init(); memset(tu,false,sizeof(tu)); memset(fuck,0,sizeof(fuck)); memset(du,0,sizeof(du)); for(i=1;i<=m;i++) { scanf("%d%d",&u,&v); if(u>30||v>30) add(u,v); du[u]++,du[v]++; if(u<=30&&v<=30) tu[u][v]=tu[v][u]=true; } fg=0; N=min(30,n); memset(use,false,sizeof(use)); ans=m; dfs(1,0); printf("%d\n",ans); } return 0; }
采用Bitset的代码如下:
#include<stdio.h> #include<iostream> #include<algorithm> #include<math.h> #include<string.h> #include<queue> #include<list> #include<bitset> using namespace std; typedef long long LL; const int nn = 550; const int inf = 0x3fffffff; const int mod = 10000003; bitset<505>be[35]; int n,m; pair<int,int>a[35]; bool use[35]; bool tu[35][35]; int N; int ans; int fg; bitset<505>bit; void dfs(int id,int val) { if(val+fg>=ans) return ; if(id==N+1) { ans=min(ans,val+fg); return ; } bool ok=true; int i; for(i=1;i<=N;i++) { if(tu[id][i]&&use[i]) ok=false; } if(ok) { use[id]=true; bitset<505>tem=bit; bit|=be[id]; fg=bit.count(); dfs(id+1,val); bit=tem; fg=bit.count(); use[id]=false; } dfs(id+1,val+1); } int main() { int i,u,v; while(scanf("%d%d",&n,&m)!=EOF) { N=min(30,n); for(i=1;i<=N;i++) { be[i].reset(); } memset(tu,false,sizeof(tu)); for(i=1;i<=m;i++) { scanf("%d%d",&u,&v); if(u>30) be[v].set(u); else if(v>30) be[u].set(v); else tu[u][v]=tu[v][u]=true; } fg=0; memset(use,false,sizeof(use)); ans=m; bit.reset(); dfs(1,0); printf("%d\n",ans); } return 0; }
相关文章推荐
- EularProject 29: a^b的归并排序问题
- 【自用】 memset对于int、long long、float、double 的极值怎么清
- [LeetCode]ZigZag Conversion
- 软件架构之-架构视图
- 我的第一篇博客
- 项目杂记一
- 第一次冲刺06
- Service完全解析
- 第一次冲刺05
- 32位与64位下各类型长度对比
- tail跟踪日志时打印时间
- 第一次冲刺04
- Using Apache Maven
- Leetcode—Contains Duplicate II—Python
- javaweb中乱码的问题
- Fragment的生命周期
- R--线性回归诊断(二)
- Verizon发布2014年数据泄露调查报告:九大攻击模式为主
- OpenCV4Android 特征点提取演示
- 第一次冲刺03