无向图最大团概念:点集中任意两点之间均可由边相连。
无向图最大独立集:任意两点无边相连。
定理:无向图最大独立集=补图最大团,反之亦然。(二分图那个很特殊)。
暴力剪枝的模板时间复杂度:o(n*2^n):(怎么能过的,,,,,,)
UVA 193 AC代码:
#include<iostream>
#define LL long long
#define par pair<int,int>
#define INF 0x3f3f3f3f
#define io ios::sync_with_stdio(false)
using namespace std;
const LL mod=18446744073709551616;
const int N=2e5+100;
const int M=2e6+100;
int mapp[550][550],mark[N];
int maxs;//当前方案中最大的点数
int ans[N];
int tot=0;//选中的点个数
void dfs(int x,int n)
{
if(x>n)
{
if(tot>maxs)
{
maxs=tot;
int kk=0;
for(int i=1;i<=n;++i)
{
if(mark[i])ans[++kk]=i;
}
}
return ;
}
bool flag=true;
for(int i=1;i<x;i++)
{
if(mark[i]&&!mapp[x][i])
{
flag=false;
break;
}
}
if(flag)
{
mark[x]=true;//这个点可以选
tot++;
dfs(x+1,n);
tot--;
}
if(tot+n-x+1>maxs)
{
mark[x]=0;
dfs(x+1,n);
}
}
int main()
{
int n,m;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(mapp,1,sizeof(mapp));//该题是求最大独立集
memset(mark,0,sizeof(mark));
memset(ans,0,sizeof(ans));
tot=0;
maxs=0;
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
mapp[x][y]=mapp[y][x]=0;//该题求最大独立集
}
dfs(1,n);
printf("%d\n",maxs);
for(int i=1;i<maxs;++i)printf("%d ",ans[i]);
printf("%d\n",ans[maxs]);
}
return 0;
}
The end;