卧薪尝胆,厚积薄发。
ZJOI2016 小星星
Date: Tue Apr 02 08:11:51 CST 2019
In Category:
NoCategory
Description:
给一棵树和一个图,问有几种把树上的点映射到图上的方式使得树上的边在原图中也有。
$1\leqslant n\leqslant17$
Solution:
考虑一种暴力树形
$DP$
:
$f[i][j][S]$
表示
$i$
的子树中
$i$
对应的点是
$j$
选取的集合为
$S$
的方案数,不难发现时间复杂度瓶颈在
$S$
,考虑
$S$
的作用,不难发现是为了保证映射是一一对应的,那么我们可以尝试让映射不是一一对应的,然后再想办法求出最后的答案,这样直接
$DP$
就不用加
$S$
那一维,转移为:
$$
f[k][j]=\prod_{i\in son[j]}\sum_{j'=1}^nf[i][j']\times map[j][j']
$$
这样的话我们会计算了一些不合法的状态,这些状态中存在一些点没有树上的点映射到他,我们考虑容斥,也就是
$2^n$
在原图上枚举删掉了哪个点,然后最后容斥,容斥的系数应该是
$\pm 1$
。
Code:
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cctype>
#include<cstring>
using namespace std;
inline int rd()
{
register int res = 0,f = 1;register char c = getchar();
while(!isdigit(c)){if(c == '-')f = -1;c = getchar();}
while(isdigit(c))res = (res << 1) + (res << 3) + c - '0',c = getchar();
return res * f;
}
int n,m;
#define MAXN 20
int map[MAXN][MAXN];
struct edge
{
int to,nxt;
}e[MAXN << 1];
int edgenum = 0;
int lin[MAXN] = {0};
void add(int a,int b)
{
e[++edgenum] = (edge){b,lin[a]};lin[a] = edgenum;
e[++edgenum] = (edge){a,lin[b]};lin[b] = edgenum;
return;
}
bool tag[MAXN];
long long f[MAXN][MAXN];
void dp(int k,int fa)
{
for(int i = 1;i <= n;++i)
{
if(!tag[i])f[k][i] = 1;
else f[k][i] = 0;
}
for(int i = lin[k];i != 0;i = e[i].nxt)
{
if(e[i].to == fa)continue;
dp(e[i].to,k);
for(int j = 1;j <= n;++j)if(!tag[j])
{
long long sum = 0;
for(int j_ = 1;j_ <= n;++j_)if(!tag[j_])
{
sum += f[e[i].to][j_] * map[j][j_];
}
f[k][j] *= sum;
}
}
return;
}
int main()
{
scanf("%d%d",&n,&m);
int a,b;
for(int i = 1;i <= m;++i)
{
a = rd();b = rd();
map[a][b] = map[b][a] = 1;
}
for(int i = 1;i < n;++i)add(rd(),rd());
int tot = (1 << n) - 1;
long long ans = 0;
for(int s = 0;s <= tot;++s)
{
int cnt = 0;
memset(tag,false,sizeof(tag));
for(int i = 1;i <= n;++i)if((s >> (i - 1)) & 1)tag[i] = true,++cnt;
dp(1,0);
long long sum = 0;
for(int i = 1;i <= n;++i)sum += f[1][i];
if(cnt % 2 == 0)ans += sum;
else ans -= sum;
}
cout << ans << endl;
return 0;
}
Copyright © 2020
wjh15101051
ღゝ◡╹)ノ♡