[ZJOI2016]小星星

题目描述

小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品。她有n颗小星星,用m条彩色的细线串了起来,每条细线连着两颗小星星。

有一天她发现,她的饰品被破坏了,很多细线都被拆掉了。这个饰品只剩下了n?1条细线,但通过这些细线,这颗小星星还是被串在一起,也就是这些小星星通过这些细线形成了树。小Y找到了这个饰品的设计图纸,她想知道现在饰品中的小星星对应着原来图纸上的哪些小星星。如果现在饰品中两颗小星星有细线相连,那么要求对应的小星星原来的图纸上也有细线相连。小Y想知道有多少种可能的对应方式。

只有你告诉了她正确的答案,她才会把小饰品做为礼物送给你呢。

输入输出格式

输入格式:

第一行包含个2正整数n,m,表示原来的饰品中小星星的个数和细线的条数。接下来m行,每行包含2个正整数u,v,表示原来的饰品中小星星u和v通过细线连了起来。这里的小星星从1开始标号。保证u&ne;v,且每对小星星之间最多只有一条细线相连。接下来n-1行,每行包含个2正整数u,v,表示现在的饰品中小星星u和v通过细线连了起来。保证这些小星星通过细线可以串在一起。n<=17,m<=n*(n-1)/2

输出格式:

输出共1行,包含一个整数表示可能的对应方式的数量。如果不存在可行的对应方式则输出0。

输入输出样例

输入样例#1:

4 3
1 2
1 3
1 4
4 1
4 2
4 3

输出样例#1:

6

说明

题解:JudgeOnline/upload/201603/4455.txt

本题题意大致是把树上的n个点赋为互不相同的1~n中的数字,同时满足连接关系,有多少方案

如果要枚举的话,复杂度会O(n!)

这种排列的问题可以转化,令状态k,是一个二进制数,为0则表示该数禁用

对于每一个k,我们求出相应的不被禁用的数的可行排列(不需要满足互不相同)

这时可以用容斥,总方案数=没有禁的方案-禁i的方案-禁j的方案+禁i,j的方案

为什么?因为禁i时,因为不考虑重复,所以可能会有一部分是j未出现的方案,等于禁j的方案

求方案数用树形dp

f[i][j]表示i点编号j的方案

f[i][j]=∏v(∑kf[v][k])  条件为图中j,k相连

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 struct Node
 7 {
 8     int next,to;
 9 }edge[2001];
10 int w,q[101],n,m,map[51][51],head[101],num;
11 long long f[21][21],ans;
12 void add(int u,int v)
13 {
14     num++;
15     edge[num].next=head[u];
16     head[u]=num;
17     edge[num].to=v;
18 }
19 void bit(int x)
20 {int p;
21     p=1;w=0;
22     while (x)
23     {
24         if (x&1) q[++w]=p;
25         p++;
26         x>>=1;
27     }
28 }
29 void dfs(int x,int fa)
30 {int i,j,k;
31     for (i=1;i<=w;i++)
32     f[x][q[i]]=1;
33         for (j=head[x];j;j=edge[j].next)
34          if (edge[j].to!=fa)
35          {
36             dfs(edge[j].to,x);
37               for (i=1;i<=w;i++)
38               {long long s=0;
39                 for (k=1;k<=w;k++)
40                 if (map[q[i]][q[k]])
41                 {
42                     s+=f[edge[j].to][q[k]];
43                 }
44                 f[x][q[i]]*=s;
45               }
46          }
47 }
48 int main()
49 {int i,j,u,v;
50 long long sum;
51     cin>>n>>m;
52      for (i=1;i<=m;i++)
53      {
54         scanf("%d%d",&u,&v);
55         map[u][v]=map[v][u]=1;
56      }
57      for (i=1;i<=n-1;i++)
58      {
59         scanf("%d%d",&u,&v);
60         add(u,v);add(v,u);
61      }
62        for (i=1;i<=(1<<n)-1;i++)
63        {
64             bit(i);
65             //cout<<w<<endl;
66             //memset(f,0,sizeof(f));
67             sum=0;
68              dfs(1,0);
69              for (j=1;j<=w;j++)
70               sum+=f[1][q[j]];
71               //cout<<sum<<endl;
72             if ((n&1)==(w&1)) ans+=sum;
73             else ans-=sum;
74        }
75     cout<<ans;
76 }
时间: 2024-10-29 19:07:25

[ZJOI2016]小星星的相关文章

4455[Zjoi2016]小星星 容斥+dp

4455: [Zjoi2016]小星星 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 527  Solved: 317[Submit][Status][Discuss] Description 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细 线连着两颗小星星.有一天她发现,她的饰品被破坏了,很多细线都被拆掉了.这个饰品只剩下了n?1条细线,但 通过这些细线,这颗小星星还是被串在一起,也就是这

[ZJOI2016]小星星&amp;[SHOI2016]黑暗前的幻想乡(容斥)

这两道题思路比较像,所以把他们放到一块. [ZJOI2016]小星星 题目描述 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细线连着两颗小星星. 有一天她发现,她的饰品被破坏了,很多细线都被拆掉了.这个饰品只剩下了n-1条细线,但通过这些细线,这颗小星星还是被串在一起,也就是这些小星星通过这些细线形成了树.小Y找到了这个饰品的设计图纸,她想知道现在饰品中的小星星对应着原来图纸上的哪些小星星.如果现在饰品中两颗小星星有细线相连,那么要求对应的

BZOJ4455: [Zjoi2016]小星星

Description 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细 线连着两颗小星星.有一天她发现,她的饰品被破坏了,很多细线都被拆掉了.这个饰品只剩下了n?1条细线,但 通过这些细线,这颗小星星还是被串在一起,也就是这些小星星通过这些细线形成了树.小Y找到了这个饰品的设 计图纸,她想知道现在饰品中的小星星对应着原来图纸上的哪些小星星.如果现在饰品中两颗小星星有细线相连, 那么要求对应的小星星原来的图纸上也有细线相连.小Y想知道有多少种

bzoj 4455: [Zjoi2016]小星星

链接 http://www.lydsy.com/JudgeOnline/problem.php?id=4455 dp+容斥题意大约是树上的点满足与图上的点一一对应并且图中两两有边,树中也两两有边,求满足条件的方案数 只保证在树在图中两两有边,用dp[i][j]表示树上i点被映射到图中的j点,以i为根的子树方案数,那么方案数可以用dp在$O(n^3)$时间内处理出来 我们把1设为树的根,那么就可以得方案数$\sum\limits_{i=1}^n f(1,i) $ 这时的方案数是有重复的,考虑容斥

4455: [Zjoi2016]小星星|状压DP|容斥原理

OrzSDOIR1ak的晨神 能够考虑状压DP枚举子集,求出仅仅保证连通性不保证一一相应的状态下的方案数,然后容斥一下就是终于的答案 #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<vector> #include<cmath> #include<queue>

【BZOJ 4455】 [Zjoi2016]小星星 容斥计数

dalao教导我们,看到计数想容斥……卡常策略:枚举顺序.除去无效状态.(树结构) #include <cstdio> #include <cstring> #include <algorithm> typedef long long LL; const int N=20; LL f[N][N]; int n,m,d[N][N],full; bool yeah[N]; int st[N],cnt; struct V{ int to,next; }c[N<<1

【BZOJ-4455】小星星 容斥 + 树形DP

4455: [Zjoi2016]小星星 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 204  Solved: 137[Submit][Status][Discuss] Description 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细线连着两颗小星星.有一天她发现,她的饰品被破坏了,很多细线都被拆掉了.这个饰品只剩下了n?1条细线,但通过这些细线,这颗小星星还是被串在一起,也就是这些小

[BZOJ4455][ZJOI2016]数星星(容斥DP)

4455: [Zjoi2016]小星星 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 707  Solved: 419[Submit][Status][Discuss] Description 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细 线连着两颗小星星.有一天她发现,她的饰品被破坏了,很多细线都被拆掉了.这个饰品只剩下了n?1条细线,但 通过这些细线,这颗小星星还是被串在一起,也就是这

SHOI2016游记&amp;滚粗记&amp;酱油记

Day0 学校刚期中考完,全科血崩,感觉这次真要考不到一本线了tat 晚上写了个可持久化trie的题,也懒得敲板子(上个礼拜都敲过了),就碎叫了 Day1 上午起床吃饭水群看球,吃完中饭就去考场了. 下雨,路上花了挺长时间,到的挺晚的.然后就开考了. 这次和LN.JL是同一套卷子,感觉丢脸要丢到外省去了啊TAT 看题,T1是一棵树,然后可以插眼啥的题,求最小费用.感觉一脸可做啊,应该是树DP,感觉做过类似的题? 不过决定先看完题目.然后再看T2,网格图挖点求正方形个数,这怎么做啊qaq 然后再看