题目链接 Sandy and Nuts
题意大概就是给出限制条件求出在该限制条件下树的种数。
#include <bits/stdc++.h>
using namespace std;
#define REP(i, n) for (int i(0); i < (n); ++i)
#define rep(i, a, b) for (int i(a); i <= (b); ++i)
#define dec(i, a, b) for (int i(a); i >= (b); --i)
typedef long long LL;
const int N = 15;
const int maxS = 10010;
const int maxQ = 210;
int n, m, q, all;
LL f[N][maxS];
int a[maxQ], b[maxQ], c[maxQ];
int e[N][N];
inline in(int i, int S){ return (S >> i) & 1; }
LL DP(int u, int S){
LL &ret = f[u][S];
if (ret != -1) return ret;
ret = 0;
int St = S ^ (1 << u);
int t; for (t = 0; t < n; ++t) if (in(t, St)) break;
for (int __S = St; __S; (--__S) &= St) if (in(t, __S)){
bool flag = true;
REP(i, n) if (i != u){
REP(j, n) if (j != u){
if (e[i][j] && (in(i, __S) ^ in(j, __S))){
flag = false;
break;
}
}
if (!flag) break;
}
if (!flag) continue;
int v, cnt = 0;
REP(i, n){
if (e[u][i] && in(i, __S)){
++cnt;
v = i;
}
}
if (cnt >= 2) continue;
rep(i, 1, q){
if (c[i] == u && in(a[i], __S) && in(b[i], __S)){
flag = false; break;
}
if (in(c[i], __S) && (!in(a[i], __S) || !in(b[i], __S))){
flag = false; break;
}
}
if (!flag) continue;
if (cnt == 1) ret += DP(v, __S) * DP(u, S ^ __S);
else REP(v, n) if (in(v, __S)) ret += DP(v, __S) * DP(u, S ^ __S);
}
return ret;
}
int main(){
scanf("%d%d%d", &n, &m, &q);
rep(i, 1, m){
int x, y;
scanf("%d%d", &x, &y);
--x, --y;
e[x][y] = e[y][x] = 1;
}
rep(i, 1, q){
scanf("%d%d%d", a + i, b + i, c + i);
--a[i], --b[i], --c[i];
}
all = (1 << n) - 1;
memset(f, -1, sizeof f);
REP(i, n) f[i][1 << i] = 1;
return 0 * printf("%lld\n", DP(0, all));
}