题解 P4547 【[THUWC2017]随机二分图】
题目
orz神仙题
考虑只有
其实等价于求完美匹配的个数,但是我们有一个更为一般的
我们可以枚举一条边
所以只有在这两条边都出现的情况下我们才会错误计算,于是我们加一条四元边
同理,对于
代码
#include <tr1/unordered_map>
#include <bits/stdc++.h>
#define re register
using namespace std::tr1;
const int mod = 1e9 + 7, inv2 = 500000004, inv4 = 250000002, _inv4 = 750000005;
unordered_map<int, int> dp, f;
inline int qm(int x) { return x >= mod ? x - mod : x; }
int se[5005], sp[5005], n, m, M;
int dfs(int s) {
if (!s)
return 1;
if (f[s])
return dp[s];
int res = 0;
f[s] = 1;
for (re int i = 1; i <= M; i++)
if ((se[i] & s) == se[i] && se[i] > s / 2)
res = qm(res + 1ll * sp[i] * dfs(se[i] ^ s) % mod);
// printf("%d %d\n",s,res);
return dp[s] = res;
}
int main() {
scanf("%d%d", &n, &m);
for (re int t, u, v, a, b, i = 1; i <= m; i++) {
scanf("%d%d%d", &t, &u, &v);
se[++M] = (1 << (u - 1)) | (1 << (v + n - 1));
sp[M] = inv2;
if (!t)
continue;
scanf("%d%d", &a, &b);
se[++M] = (1 << (a - 1)) | (1 << (b + n - 1));
sp[M] = inv2;
if (se[M] & se[M - 1])
continue;//当(a,b),(u,v)有交点的时候,由于不可能同时存在于完美匹配里,所以没有必要加入四元边
se[M + 1] = se[M] | se[M - 1];
sp[++M] = (t == 1 ? inv4 : _inv4);
}
// for(re int i=1;i<=M;i++) printf("%d %d\n",se[i],sp[i]);
printf("%d\n", 1ll * (1 << n) * dfs((1 << (n + n)) - 1) % mod);
return 0;
}