传送门

思路
对每个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;
}
这篇博客主要介绍了一种使用并查集求解独立子集合的方法。通过将集合映射为二进制数,并根据二进制位进行操作,计算出不重复的独立子集合。算法涉及到位运算和动态规划,最终计算出所有集合的组合并输出答案。
1470

被折叠的 条评论
为什么被折叠?



