[ZJOI2016]小星星
题目描述
小 Y 是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品。她有 \(n\) 颗小星星,用 \(m\) 条彩色的细线串了起来,每条细线连着两颗小星星。
有一天她发现,她的饰品被破坏了,很多细线都被拆掉了。这个饰品只剩下了 \(n-1\) 条细线,但通过这些细线,这颗小星星还是被串在一起,也就是这些小星星通过这些细线形成了树。小 Y 找到了这个饰品的设计图纸,她想知道现在饰品中的小星星对应着原来图纸上的哪些小星星。如果现在饰品中两颗小星星有细线相连,那么要求对应的小星星原来的图纸上也有细线相连。小 Y 想知道有多少种可能的对应方式。
只有你告诉了她正确的答案,她才会把小饰品做为礼物送给你呢。
输入格式
第一行包含 \(2\) 个正整数 \(n,m\),表示原来的饰品中小星星的个数和细线的条数。
接下来 \(m\) 行,每行包含 \(2\) 个正整数 \(u,v\),表示原来的饰品中小星星 \(u\) 和 \(v\) 通过细线连了起来。这里的小星星从 \(1\) 开始标号。保证 \(u\neq v\),且每对小星星之间最多只有一条细线相连。
接下来 \(n-1\) 行,每行包含 \(2\) 个正整数 \(u,v\),表示现在的饰品中小星星 \(u\) 和 \(v\) 通过细线连了起来。保证这些小星星通过细线可以串在一起。
输出格式
输出共 \(1\) 行,包含一个整数表示可能的对应方式的数量。
如果不存在可行的对应方式则输出 0
。
样例 #1
样例输入 #1
4 3
1 2
1 3
1 4
4 1
4 2
4 3
样例输出 #1
6
提示
对于 \(100\%\) 的数据,\(n\leq 17\),\(m\leq \frac 12n(n-1)\)。
这题到现在已经变成了模板题了。
如果这题想要直接dp,就肯定逃不开状压。在一棵树上,跑一个状压背包,看起来还要用FWT优化。是可以这样做,不过有一种简单很多的方法。
我们为什么要状压?无非就是为了让所有的点都用到。让所有的点都用到,想到了容斥。
在 dp 的外面枚举在图中用到的点集 \(S\),然后定义 \(dp_{i,j}\) 表示如果点 \(i\) 对应图中点 \(j\) 的方案数。枚举另一个树上的点在图上对应哪一个点,并保证图上的点只用 \(S\) 中的点,跑出来 dp 值乘上 \((-1)^{|S|}\) 累积到答案上就行了。
#include<bits/stdc++.h>
typedef long long LL;
const int N=20;
int n,m,hd[N],e_num,g[N][N],cnt;
LL dp[N][N],ans,ret,s;
struct edge{
int v,nxt;
}e[N<<1];
void add_edge(int u,int v)
{
e[++e_num]=(edge){v,hd[u]} ;
hd[u]=e_num;
}
void dfs(int x,int y,int z)
{
// printf("%d %d %d\n",x,y,z);
for(int i=hd[x];i;i=e[i].nxt)
if(e[i].v!=z)
dfs(e[i].v,y,x);
for(int i=0;i<n;i++)
{
dp[x][i]=0;
if(!(y>>i&1))
continue;
dp[x][i]=1;
for(int k=hd[x];k;k=e[k].nxt)
{
if(e[k].v==z)
continue;
s=0;
for(int j=0;j<n;j++)
if(g[i+1][j+1]&&(y>>j&1))
s+=dp[e[k].v][j];
dp[x][i]*=s;
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1,u,v;i<=m;i++)
{
scanf("%d%d",&u,&v);
g[u][v]=g[v][u]=1;
}
for(int i=1,u,v;i<n;i++)
{
scanf("%d%d",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
for(int i=1;i<(1<<n);i++)
{
cnt=0,ans=0;
for(int j=0;j<n;j++)
if(i>>j&1)
++cnt;
dfs(1,i,0);
for(int j=0;j<n;j++)
ans+=dp[1][j];
ret+=(n-cnt&1)? -ans:ans;
// printf("%d %d\n",i,ans);
}
printf("%lld ",ret);
}
标签:int,小星星,细线,饰品,ZJOI2016,对应,dp
From: https://www.cnblogs.com/mekoszc/p/17065620.html