【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$。
限制与约定
各测试点满足以下约定:
测试点 | $n$ | $m$ | 约定 |
---|---|---|---|
1 | $=10$ | $\leq \frac {n(n-1)} {2}$ | 无 |
2 | |||
3 | $=17$ | 保证新的饰品中每颗小星星与至多两颗小星星相连 | |
4 | |||
5 | $=14$ | 无 | |
6 | |||
7 | $=16$ | 保证答案不超过 $10^5$ | |
8 | 无 | ||
9 | $=17$ | ||
10 |
时间限制:$1\texttt{s}$
空间限制:$512\texttt{MB}$
我们对于这一类计数问题,考虑容斥来做
这道题目其实就是对树上的结点进行重新标号,使得树上存在边的在图中也存在
那么,我们用\(f[i][j]\)表示树上结点\(i\),对于图中标号\(j\)的方案数
显然\(f[i][j]=\prod_{}^{} (\sum f[x][k])(x\in C(i),(j,k)存在)\),树形dp,时间复杂度\(O(n^3)\)
暴力枚举容斥的状态\(O(2^n)\),总的时间复杂度是\(O(2^n*n^3)\),再卡卡常数就过了
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<climits>
#include<vector>
#include<cmath>
#include<map>
#include<set>
#define LL long long
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc();int b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
inline void read(LL &x){
char c=nc();LL b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
inline int read(char *s)
{
char c=nc();int len=0;
for(;!(c>='A' && c<='Z');c=nc()) if (c==EOF) return 0;
for(;(c>='A' && c<='Z');s[len++]=c,c=nc());
s[len++]='\0';
return len;
}
inline void read(char &x){
for (x=nc();!(x>='A' && x<='Z');x=nc());
}
int wt,ss[19];
inline void print(int x){
if (x<0) x=-x,putchar('-');
if (!x) putchar(48); else {
for (wt=0;x;ss[++wt]=x%10,x/=10);
for (;wt;putchar(ss[wt]+48),wt--);}
}
inline void print(LL x){
if (x<0) x=-x,putchar('-');
if (!x) putchar(48); else {for (wt=0;x;ss[++wt]=x%10,x/=10);for (;wt;putchar(ss[wt]+48),wt--);}
}
int n,m,a[20][20],b[20],fa[20];
LL ans,f[20][20],p[20];
vector<int> c[20],d[20];
void dp(int x)
{
for (int i=1;i<=n;i++)
if (b[i]) f[x][i]=1LL;
for (int i=0;i<d[x].size();i++)
dp(d[x][i]);
if (x==1) return ;
for (int j=1;j<=n;j++)
p[j]=0;
for (int j=1;j<n;j++)
for (int k=j+1;k<=n;k++)
if (a[j][k] && b[j] && b[k]) p[j]+=f[x][k],p[k]+=f[x][j];
for (int j=1;j<=n;j++)
f[fa[x]][j]*=p[j];
}
LL calc()
{
memset(f,0,sizeof(f));
dp(1);
LL res=0;
for (int i=1;i<=n;i++)
res+=f[1][i];
return res;
}
void work(int x)
{
if (x==n+1)
{
int s=0;LL f;
for (int i=1;i<=n;i++)
s+=b[i];
if (s%2==n%2) f=1LL;else f=-1LL;
ans+=f*calc();
return ;
}
for (int i=0;i<=1;i++)
b[x]=i,work(x+1);
}
void dfs(int x)
{
for (int i=0;i<c[x].size();i++)
if (fa[c[x][i]]==-1)
{
fa[c[x][i]]=x;
d[x].push_back(c[x][i]);
dfs(c[x][i]);
}
}
int main()
{
read(n);read(m);
int x,y;
for(int i=1;i<=m;i++)
read(x),read(y),a[x][y]=1,a[y][x]=1;
memset(b,0,sizeof(b));
for (int i=1;i<n;i++)
read(x),read(y),c[x].push_back(y),c[y].push_back(x);
memset(fa,-1,sizeof(fa));
fa[1]=0;
dfs(1);
ans=0;
work(1);
print(ans),puts("");
return 0;
}
【ZJOI2016】小星星的更多相关文章
- BZOJ 4455: [Zjoi2016]小星星 [容斥原理 树形DP]
4455: [Zjoi2016]小星星 题意:一个图删掉一些边形成一棵树,告诉你图和树的样子,求让图上的点和树上的点对应起来有多少方案 看了很多题解又想了一段时间,感觉题解都没有很深入,现在大致有了自 ...
- 4455[Zjoi2016]小星星 容斥+dp
4455: [Zjoi2016]小星星 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 527 Solved: 317[Submit][Status] ...
- [ZJOI2016]小星星&[SHOI2016]黑暗前的幻想乡(容斥)
这两道题思路比较像,所以把他们放到一块. [ZJOI2016]小星星 题目描述 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细线连着两颗小星星. ...
- 【BZOJ 4455】 4455: [Zjoi2016]小星星 (容斥原理+树形DP)
4455: [Zjoi2016]小星星 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 426 Solved: 255 Description 小Y是 ...
- 洛谷 P3349 [ZJOI2016]小星星 解题报告
P3349 [ZJOI2016]小星星 题目描述 小\(Y\)是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有\(n\)颗小星星,用\(m\)条彩色的细线串了起来,每条细线连着两颗小星星. 有一 ...
- bzoj 4455 [Zjoi2016]小星星 树形dp&容斥
4455: [Zjoi2016]小星星 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 643 Solved: 391[Submit][Status] ...
- 【题解】P3349 [ZJOI2016]小星星 - 子集dp - 容斥
P3349 [ZJOI2016]小星星 声明:本博客所有题解都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 题目描述 小 \(Y\) 是一个心灵手巧 ...
- ZJOI2016 小星星 题解
我一生之敌是状压 本文发表于 洛谷博客:https://www.luogu.com.cn/blog/LoveMC/solution-p3349 Cnblogs:https://www.cnblogs. ...
- BZOJ4455: [Zjoi2016]小星星
Description 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细 线连着两颗小星星.有一天她发现,她的饰品被破坏了,很多细线都被拆掉了.这 ...
- [ZJOI2016]小星星
题目描述 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细线连着两颗小星星. 有一天她发现,她的饰品被破坏了,很多细线都被拆掉了.这个饰品只剩下了 ...
随机推荐
- python-面试常用 --变量、内存管理(小整数池,引用计数)
执行Python程序的两种方法 第一种:交互式(jupyter就是对这种进行了封装) 优点:直接给出结果 缺点:无法保存 第二种:命令行式,通过Python解释器输入文本(pycharm对这种进行了封 ...
- python基础之文件处理总结
读文件: with open('contacts.txt', 'r', encoding='utf-8') as f: data = f.read() 二进制模式读 使用场景:网络传输(视频.图片或进 ...
- LeetCode(189) Rotate Array
题目 Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, the arr ...
- hdu 6301
Distinct Values Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- InnoDB Redo Flush及脏页刷新机制深入分析
概要: 我们知道InnoDB采用Write Ahead Log策略来防止宕机数据丢失,即事务提交时,先写重做日志,再修改内存数据页,这样就产生了脏页.既然有重做日志保证数据持久性,查询时也可以直接从缓 ...
- UOJ 152 汉诺塔 分治
题目链接 题意: 有三根编号为\((1, \, 2, \, 3)\)的柱子,然后第一根柱子上有编号为\(1 \sim n(n \leq 10000)\)的盘子,从上到下第\(i\)个盘子的编号是\(A ...
- css 透明度使用
设置元素整体透明度: div{ opacity: 0.5; } 设置背景色透明度 div{ background: rgba(0,0,0,0.5); }
- Ubuntu超简单文书编辑器:nano
nano 的使用很简单,可以直接加上档名就能够开启一个旧档或新档! 直接在终端输入指令:nano text.txt,如下图所示打开的是已有的文档! 第一部分反白部分,是nano的版本与档名 第二部分可 ...
- 蓝桥杯Java输入输出相关
转载自:http://blog.csdn.net/Chen_Tongsheng/article/details/53354169 一.注意点 1. 类名称必须采用public class Main方式 ...
- oracle 控制文件的重建
目录 oracle 控制文件的重建 NORESETLOGS RESETLOGS oracle 控制文件的重建 不到最后时刻,如三个控制文件都已损坏,又没有控制文件的备份.还是不要重建控制文件,处理不好 ...