问题描述:团就是最大完全子图。
给定无向图G=(V,E)。如果UV,且对任意u,vU 有(u,v) E,则称U 是G 的完全子图。(U中任意两点间相连)
G 的完全子图U是G的团当且仅当U不包含在G 的更大的完全子图中,即U就是最大完全子图。
G 的最大团是指G中所含顶点数最多的团。
例如:
(a) (b) (c) (d)
图a是一个无向图,图b、c、d都是图a的团,且都是最大团。
tips:子集树搜索,只有当前点与团中所有的点都相连时,将该点加入团中。如果不将当前点加入团中,须满足剩下的所有的点加上当前团中的点比已知解更优。
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
vector<int>v;
int map[15][15];
int tmp[15];//1代表当前下标节点在团中
int n,m;//定点从一开始编号
int ans;
void dfs(int step,int cnt)
{
if(step>n)
{
ans=cnt;
v.clear();
for(int i=1;i<=n;i++)
{
if(tmp[i])v.push_back(i);
}
return;
}
int flag=1;
for(int i=1;i<step;i++)
{
if(tmp[i]==1&&map[step][i]==0){
flag=0;break;
}
}
if(flag)
{
tmp[step]=1;
dfs(step+1,cnt+1);
tmp[step]=0;//别忘记回溯
}
if(cnt+(n-step)>ans){
tmp[step]=0;
dfs(step+1,cnt);
}
}
int main()
{
while(cin>>n>>m)
{
v.clear();ans=0;memset(map,0,sizeof(map));
memset(tmp,0,sizeof(tmp));
for(int i=1;i<=m;i++)
{
int x,y;cin>>x>>y;
map[x][y]=map[y][x]=1;
}
dfs(1,0);
for(int i=0;i<v.size();i++)cout<<v[i]<<" ";cout<<endl;
}
return 0;
}
/*
5 7
1 2
1 4
1 5
2 5
4 5
2 3
5 3
*/