思路就是,设 fS 表示集合 S 里面的点的最大团,转移枚举 lowbit,考虑不选则转移到 S-lowbit,否则,和这个lowbit 有边的点都不能选,转移到 S&e[lowbit]+1。(细节可以看代码)
这个做法看起来状态是 2n 级别,但是过了,求证明复杂度/hack
#include<iostream>
#include<cstdio>
#include<map>
#include<string>
#include<iomanip>
#define int long long
using namespace std;
int e[55],n;
map<int,int> mp,f;
int dfs(int now)
{
if(now==0) return 0;
if(mp.find(now)!=mp.end()) return mp[now];
int lb=(now&(-now));
return mp[now]=max(dfs(now-lb),dfs(now&e[f[lb]])+1);
}
signed main()
{
int k;
cin>>n>>k;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
int x;
cin>>x;
if(x==1)
e[i]|=1ll<<j;
}
}
for(int i=0;i<n;i++)
f[1ll<<i]=i;
double ans=dfs((1ll<<n)-1);
ans=k*k/ans*(ans-1)/2;
cout<<fixed<<setprecision(10)<<ans;
return 0;
}