博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 2989 All Friends 极大团计数
阅读量:5046 次
发布时间:2019-06-12

本文共 1466 字,大约阅读时间需要 4 分钟。

 

题意:给定一个无向图(节点数小于128)求极大团(不包含在更大的团中)的总数。

对最大团,极大团不熟悉的,建议先阅读最大团搜索问题  再来看本题。

本题数据有限,可以使用dfs解决。类似于搜索最大团的加强版。有“两个”剪枝需要注意。

 

 

在dfs中需要维护两个集合即 Not(已经尝试过搜索极大团的节点)和Candidate(未曾尝试过的节点)由于极大团带有集合的性质,故某个节点在dfs序列中出现的位次并不重要。

当Not和Can集合同时为空时结束dfs。

在代码中,Not节点集合用ne数组标记,Can节点集合用ce数组标记

剪枝1:若当前Not集合中存在一个点,与Can中所有点都相连,则在未来的搜索中它永远不会离开Not集合,故剪枝。

剪枝2:这个剪枝为了优化剪枝1的效果,并不是一个新的剪枝。

    原本的搜索我们总是从Can集合中随意选择一个继续dfs 但是我们可以挑选一个特殊的节点,来增强剪枝1的效果。

           设每个在Not集合中的节点有一个cnt值,为Can集合中与它不相连的节点个数。

           我们于是选择Can集合中与cnt最小的节点不相连的节点进行下一步dfs。

代码如下

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;const int maxn=130;int n,m,ans,ne[maxn],ce[maxn],list[maxn][maxn];bool g[maxn][maxn];void dfs(int size){ if(ans>1000)return ; int i,j,k,t,cnt,best=0; if(ne[size]==ce[size]) { if(ce[size]==0)++ans; return ; } for(t=0,i=1;i<=ne[size];++i) { for(cnt=0,j=ne[size]+1;j<=ce[size];++j) if(!g[list[size][i]][list[size][j]])++cnt; if(t==0||cnt
0) { for(i=k;i<=ce[size];++i) if(!g[list[size][t]][list[size][i]])break; swap(list[size][k],list[size][i]);//最大化剪枝1 } i=list[size][k]; ne[size+1]=ce[size+1]=0; for(j=1;j
1000)return ; ++ne[size]; --best; for(j=k+1,cnt=0;j<=ce[size];++j) if(!g[i][list[size][j]]) ++cnt; if(t==0||cnt
1000)printf("Too many maximal sets of friends.\n"); else printf("%d\n",ans); } return 0;}

  

转载于:https://www.cnblogs.com/heisenberg-/p/6481245.html

你可能感兴趣的文章
phpcms 添加自定义表单 留言
查看>>
mysql 优化
查看>>
读书笔记 ~ Nmap渗透测试指南
查看>>
WCF 配置文件
查看>>
动态调用WCF服务
查看>>
oracle导出/导入 expdp/impdp
查看>>
类指针
查看>>
css修改滚动条样式
查看>>
2018.11.15 Nginx服务器的使用
查看>>
Kinect人机交互开发实践
查看>>
百度编辑器UEditor ASP.NET示例Demo 分类: ASP.NET...
查看>>
JAVA 技术类分享(二)
查看>>
android客户端向服务器发送请求中文乱码的问
查看>>
Symfony翻译教程已开课
查看>>
TensorFlow2.0矩阵与向量的加减乘
查看>>
NOIP 2010题解
查看>>
javascript中的each遍历
查看>>
String中各方法多数情况下返回新的String对象
查看>>
浅谈tcp粘包问题
查看>>
UVA11524构造系数数组+高斯消元解异或方程组
查看>>