传送门
思路
对每个T集合,求独立子集合
把一个集合对应成二进制数按以下方式划分,
- 没有最低位 : 只有高位,直接加上高位表达的集合
- 有最低位
①只有最低位这个位:加上这个低位表达的集合
②除了最低位还有其它高位:加上与低位无边的高位集合
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 26;
const ll mod = 1e9 + 7;
int dp[1 << N ];// T集合i
int mk[1 << N];
int e[N];
int main(){
int n,m; cin >> n >> m;
for(int i = 0; i < n; ++i) mk[1 << i] = i;
for(int i = 1; i <= m; ++i){
int x,y; cin >> x >> y;
e[x] |= (1 << y);
e[y] |= (1 << x);
}
ll ans = 0;
for (int i = 1; i < (1 << n); ++i){//不重复的求出所有独立集
int id = mk[i&(-i)];
if(1 << id == i) dp[i] = 1;// 如果只有一位就是 1
else
dp[i] = 1LL *(dp[i ^ (1 << id)] + dp[1 << id] + dp[i^(1 << id)^(i&e[id])])%mod;// 无低位 + 只有低位 + 与低位无边的高位集合
}
for(int i = (1 << n) - 1; i >= 0; --i) ans = (1LL*233 * ans + 1LL*dp[i] + 1) % mod; // 注意给每个集合加上空集
cout << ans ;
return 0;
}