POJ 2989 All Friends 极大团计数
题意:给定一个无向图(节点数小于128)求极大团(不包含在更大的团中)的总数。
对最大团,极大团不熟悉的,建议先阅读最大团搜索问题 ZOJ 1492 再来看本题。
本题数据有限,可以使用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<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#include<queue>
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<best)t=i,best=cnt;
}
if(t&&best<=0)return ;//剪枝1
for(k=ne[size]+1;k<=ce[size];++k)
{
if(t>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<k;++j)
if(g[i][list[size][j]])
list[size+1][++ne[size+1]]=list[size][j];
for(ce[size+1]=ne[size+1],j=k+1;j<=ce[size];++j)
if(g[i][list[size][j]])
list[size+1][++ce[size+1]]=list[size][j];
dfs(size+1);
if(ans>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<best)t=k,best=cnt;
if(t&&best<=0)break;
}
} void cluster_count()
{
int i;
ne[0]=0;ce[0]=0;
for(i=1;i<=n;++i)
list[0][++ce[0]]=i;
ans=0;
dfs(0);
} int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(g,0,sizeof(g));
for(int i=0;i<m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
g[a][b]=g[b][a]=true;
}
cluster_count();
if(ans>1000)printf("Too many maximal sets of friends.\n");
else printf("%d\n",ans);
}
return 0;
}
POJ 2989 All Friends 极大团计数的更多相关文章
- All Friends 极大团
搞懂了什么是团 什么是极大团 什么是最大团 极大团就是 不是任何团的真子集 最大团就是点数最多的极大团 这题就是求极大团的个数 用bk算法 #include <iostream> ...
- hdoj1373 Channel Allocation(极大团)
题意是有若干个接收器,给出每个接收器的相邻接收器.相邻的接收器不能使用同一信号频道.问所需要的信号频道数. 求该无向图的极大团. #include<iostream> #include&l ...
- Codeforces 839E Mother of Dragons(极大团)
[题目链接] http://codeforces.com/contest/839/problem/E [题目大意] 现在有一些点,现在你有k的液体,随意分配给这些点, 当两个点有边相连的时候,他们能产 ...
- POJ 3692 Kindergarten (二分图 最大团)
Kindergarten Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5660 Accepted: 2756 Desc ...
- POJ 3692 Kindergarten(最大团问题)
题目链接:http://poj.org/problem?id=3692 Description In a kindergarten, there are a lot of kids. All girl ...
- POJ 2409 Let it Bead(polay计数)
题目链接:http://poj.org/problem?id=2409 题意:给出一个长度为m的项链,每个珠子可以用n种颜色涂色.翻转和旋转后相同的算作一种.有多少种不同的项链? 思路: (1) 对于 ...
- poj 1952 最长公共子序列计数
看代码就懂了 不解释 3 1 1 1 1 2 2 2 1 1 1 3 第一个3 和最后一个 3 只需要一个就够了,,, #include<iostream> #include< ...
- [ACM] POJ 2409 Let it Bead (Polya计数)
参考:https://blog.csdn.net/sr_19930829/article/details/38108871 #include <iostream> #include < ...
- poj 2409 Let it Bead Polya计数
旋转能够分为n种置换,相应的循环个数各自是gcd(n,i),个i=0时不动,有n个 翻转分为奇偶讨论,奇数时有n种置换,每种有n/2+1个 偶数时有n种置换,一半是n/2+1个,一半是n/2个 啃论文 ...
随机推荐
- 理解Twisted与非阻塞编程
先来看一段代码: # ~*~ Twisted - A Python tale ~*~ from time import sleep # Hello, I'm a developer and I mai ...
- vim中多行注释 和 删除多行注释
1.多行注释: a. 按下ctrl + v,进入列模式; b. 在行首选择需要注释的行; c. 按下"I",进入插入模式: d. 然后输入注释符("//&q ...
- Intent的概念及应用(二)
------siwuxie095 1.Intent过滤器 intent-filter 相关选项 如果多个Activity拥有同样的action,在启动时这个action时的情况: 首先在LearnIn ...
- 搭建自己的BT下载平台服务器
[原理基础] BT(Bit Torren比特流)是由国外的一名叫Bram Cohen的程序员开发的下载软件,可以说它是目前网络是非常流行的一个多点下载的P2P软件,它最显著的特点就是:下载的人越多,速 ...
- 使用ProgressDialog创建进度对话框
ProgressDialog代表了进度对话框,程序只要创建ProgressDialog实例,并将它显示出来就是一个进度对画框.使用ProgressDialog创建进度对话框有如下两种方式. ①如果只是 ...
- P2P之UDP穿透NAT的原理与实现
首先先介绍一些基本概念: NAT(Network Address Translators),网络地址转换:网络地址转换是在IP地址日益缺乏的情况下产生的,它的主要目的就是为了能够地址重用.NAT分为两 ...
- SLS评测报告
什么是SLS? 简单日志服务(Simple Log Service,简称SLS)是针对日志收集.存储.查询和分析的服务.用户只需简单地配置日志产生的位置和格式等信息,就能实时查询海量日志,并可通过S ...
- MySQL各存储引擎
MySQL中的数据用各种不同的技术存储在文件(或者内存)中.这些技术中的每一种技术都使用不同的存储机制.索引技巧.锁定水平并且最终提供广泛的不同的功能和能力.通过选择不同的技术,你能够获得额外的速度或 ...
- 支付宝 Android 版使用的开源组件
支付宝 Android 版使用的开源组件 前言: 花了点时间整理了 支付宝 Android 客户端使用的开源组件,给需要的同学.在你不知道用什么开源框架的时候可以作下参考,毕竟支付宝是阿里的重量级产品 ...
- HDU3652(数位dp)
A - B-number Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Descri ...