# 2018-8-10考试 T3. 招募(akekure)

$$令f_{i,j}表示在第i个点，它的状态为j（1为黑，0为白）$$
$$f_{i,0}=\prod\limits_{j为i的儿子}(f_{j,0}+f_{j,1})（因为它的儿子没有限制，可以黑可以白）$$
$$f_{i,0}=\prod\limits_{j为i的儿子}f_{j,0}（它的儿子有限制，必须为白）$$

C++ Code：

#include <cstdio>
#include <cctype>
#define maxn 100100
using namespace std;
const long long mod = 1000000007;
const long long half = 500000004;
int n, m;
long long ans;
int fa[maxn], oth[50], tot;
int f[maxn][2];

struct Edge {
int from, to, nxt;
bool can;
} e[(maxn + 10) << 1];
void add(int a, int b) {
}

char *ch, op[1 << 25 | 100];
x = 0;
while (isspace(*ch)) ch++;
while (isdigit(*ch)) x = x * 10 + (*ch++ & 15);
}

bool vis[maxn];
void dfs(int rt) {
vis[rt] = true;
int v;
for (register int i = head[rt]; i; i = e[i].nxt) {
v = e[i].to;
if (v != fa[rt]) {
if (!vis[v]) {
fa[v] = rt;
dfs(v);
} else {
e[i].can = false;
if (v > rt) oth[++tot] = i;
}
}
}
}
bool ispoint[maxn], mus[maxn];
inline void real(int rt) {
int v;
int &_0 = f[rt][0], &_1 = f[rt][1];
_0 = _1 = 1;
if (ispoint[rt]) f[rt][mus[rt] ^ 1] = 0;
for (int i = head[rt]; i; i = e[i].nxt) {
if (e[i].can) {
v = e[i].to;
if (v != fa[rt]) {
real(v);
_0 = (1ll * _0 * (f[v][1] + f[v][0])) % mod;
_1 = (1ll * _1 * f[v][0]) % mod;
}
}
}
}
void run(int x) {
if (x > tot) {
real(1);
ans = (ans + f[1][1] + f[1][0]) % mod;
return ;
}
int u = e[oth[x]].from, v = e[oth[x]].to;
bool &iu = ispoint[u], &iv = ispoint[v], &mu = mus[u], &mv = mus[v];
if (iu && iv) {
run(x + 1);
return ;
}
if (iu || iv) {
if (iv) u ^= v ^= u ^= v;
if (mus[u]) {
ispoint[v] = true;
mus[v] = false;
run(x + 1);
ispoint[v] = false;
} else {
run(x + 1);
}
return ;
}
iu = true;
mu = false;
run(x + 1);
iu = false;
iu = iv = true;
mu = true;
mv = false;
run(x + 1);
iv = iu = false;
}
int main() {
fread(ch = op, 1, 1 << 25, stdin);
for (register int i = 0; i < m; i++) {
int a, b;
}
dfs(1);
run(1);
printf("%lld\n", ans);
return 0;
}


2018-8-10考试 T3. 招募(akekure)

(0)
(0)

0条