最大团,最大独立集
来源:互联网 发布:国家网络安全法 编辑:程序博客网 时间:2024/06/05 20:53
最大团,最大独立集
最大独立集:一个图中最大的互相没有边相连的点集。
结论:原图的最大独立集等于补图的最大团
经典的NP完全问题,只有暴力解,时间复杂度O(n2^n)
对于无向图来说
所谓最大团, 其实就是找一个最大完全子图,最大就是包含的点最多.
而最大独立集== 补图的最大团
这里使用深度优先搜索实现,对于每一个结点,考虑要与不要两种状态,则问题构成一个子集树,本质上与01背包一样,只不过多了联通性的判断
// 最大独立集的做法,求出最大独立集,并且打印方案
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include<vector>
using namespace std;
vector<vector<int> > G;
int n, m;
int color[123];
vector<int> rec;
int maxnum;
void dfs(int u,int _count) {
if (_count > maxnum) {//更新答案
maxnum = _count;
rec.clear();
for (int i = 1;i <= n;++i) {
if (color[i]) rec.push_back(i);
}
}
if (u == n + 1) return ;
//用于判断是否可以染成黑色
bool ok = true;
for (int i = 0;i < G[u].size();++i) {
if (color[G[u][i]]) ok = false;
}
if (ok) {//u节点可以染成黑色
color[u] = 1;
dfs(u + 1, _count + 1);
color[u] = 0;
}
dfs(u + 1, _count);//u染成白色->跳过
}
int main(int argc, const char * argv[])
{
int t, u, v;
cin >> t;
while(t--) {
scanf("%d%d", &n, &m);
G.clear();
G.resize(n + 2);
while(m--) {
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
memset(color, 0,sizeof color);
maxnum = 0;
dfs(1, 0);
printf("%d\n", maxnum);
for (int i = 0;i < rec.size();++i)
printf("%d%c", rec[i], i == maxnum - 1?'\n':' ');
}
return 0;
}
//用最大团求最大独立子集
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
using namespace std;
int N, M, mp[105][105];
int ret, cnt, opt[105], st[105];
void dfs(int x) {
if (x > N) { // 如果枚举了所有的节点
ret = cnt;
memcpy(opt, st, sizeof (st)); // 用一个更大的极大团替代原有的极大团
return;
}
int flag = true;
for (int i = 1; i < x; ++i) { // 检测新加入的点是否到团中的其他节点都存在一条边
if (st[i] && !mp[i][x]) {
flag = false;
break;
}
}
if (flag) { // 如果该节点满足在这个团中
st[x] = 1, ++cnt; // 该节点被加入到完全子图中去
dfs(x + 1);
st[x] = 0, --cnt;
}
if (cnt+N-x > ret) { // 跳过x节点进行搜索同时进行一个可行性判定
dfs(x + 1);
}
}
int main() {
int T, x, y;
scanf("%d", &T);
while (T--) {
ret = cnt = 0;
scanf("%d %d", &N, &M);
memset(st, 0, sizeof (st));
for (int i = 0; i < 105; ++i) {
fill(mp[i], mp[i]+105, 1);
}
while (M--) {
scanf("%d %d", &x, &y);
mp[x][y] = mp[y][x] = 0;
}
dfs(1);
printf("%d\n", ret);
for (int i = 1, j = 0; i <= N; ++i) {
if (opt[i]) {
printf(j == 0 ? "%d" : " %d", i);
++j;
}
}
puts("");
}
return 0;
}
阅读全文
0 0
- 最大团,最大独立集
- 图论 最大团,最大独立集
- 独立集,覆盖集,支配集,最大团,最大匹配
- 独立集,覆盖集,支配集,最大团,最大匹配
- 独立集,覆盖集,支配集,最大团,最大匹配
- 独立集,覆盖集,支配集,最大团,最大匹配
- POJ3692 二分图最大团 最大独立集
- 无向图的最大团与最大独立集
- POJ 3692 Kindergarten 最大团->最大独立集
- POJ 1419 最大独立集(即最大团)
- Bron–Kerbosch算法-最大独立集与最大团
- POJ 1419 Graph Coloring(最大独立集、最大团)
- 无向图的最大独立集和最大团
- poj1419 点独立集/最大团
- poj1185 点独立集/最大团
- 【最小边覆盖 & 最小路径覆盖 & 最小顶点覆盖 & 最大独立集 & 最大团】
- 二分图的最小路径覆盖,最大独立集,最大团,支配数之间关系证明
- 最大独立集 最小点覆盖 最小边覆盖 最小路径覆盖 最大团
- 天平
- spring 注解 AOP
- 库的编译
- python 检测白名单外的非法进程的进程树和链接信息
- NIOP2012普及组-文化之旅
- 最大团,最大独立集
- java代码对MongoDB的CRUD
- 关于树的总结
- 换源,安装ssh,lamp
- myeclipse在运行时tomcat 5.5.23启动不了
- iOS图片实现可拉伸不变形的处理操作
- rmq 求区间内出现次数最多的数字出现的次数!
- 深入理解Java中的自增
- 二进制数中的1的个数