[BZOJ4455][Zjoi2016]小星星

来源:互联网 发布:数据库设计视频教程 编辑:程序博客网 时间:2024/04/29 05:56

[Zjoi2016]小星星

Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 60 Solved: 52
[Submit][Status][Discuss]
Description
小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品。她有n颗小星星,用m条彩色的细线串了起来,每条细线连着两颗小星星。有一天她发现,她的饰品被破坏了,很多细线都被拆掉了。这个饰品只剩下了n-1条细线,但通过这些细线,这颗小星星还是被串在一起,也就是这些小星星通过这些细线形成了树。
小Y找到了这个饰品的设计图纸,她想知道现在饰品中的小星星对应着原来图纸上的哪些小星星。如果现在饰品中两颗小星星有细线相连,那么要求对应的小星星原来的图纸上也有细线相连。
小Y想知道有多少种可能的对应方式。只有你告诉了她正确的答案,她才会把小饰品做为礼物送给你呢。
Input
第一行包含个2正整数n,m,表示原来的饰品中小星星的个数和细线的条数。
接下来m行,每行包含2个正整数u,v,表示原来的饰品中小星星u和v通过细线连了起来。
这里的小星星从1开始标号。保证u≠v,且每对小星星之间最多只有一条细线相连。
接下来n-1行,每行包含个2正整数u,v,表示现在的饰品中小星星u和v通过细线连了起来。
保证这些小星星通过细线可以串在一起。
Output
输出共1行,包含一个整数表示可能的对应方式的数量。如果不存在可行的对应方式则输出0。
Sample Input
4 3
1 2
1 3
1 4
4 1
4 2
4 3
Sample Output
6

Solution
所有的映射方案视作一个集合S(不管一个点被映射几次,只要连通性满足即可),我们要求对其中的一些映射进行计数,这些映射满足的条件是恰好包含每一个点
我们记Ai表示包含点i的映射方案集合,那么我们实际上要求的就是所有A的交集
利用容斥原理即可

Code

#include <bits/stdc++.h>using namespace std;#define rep(i, l, r) for (int i = (l); i <= (r); i++)#define per(i, r, l) for (int i = (r); i >= (l); i--)#define MS(_) memset(_, 0, sizeof(_))#define MP make_pair#define PB push_back#define debug(...) fprintf(stderr, __VA_ARGS__)typedef long long ll;typedef pair<int, int> PII;typedef vector<int> VI;template<typename T> inline void read(T &x){    x = 0; T f = 1; char ch = getchar();    while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getchar(); }    while (isdigit(ch))  { x = x * 10 + ch - '0'; ch = getchar(); }    x *= f;}int n, m, cnt, g[20][20], lst[20];ll dp[20][20];struct Node{int v; Node *nxt;}pool[200], *tail=pool, *last[20];inline void addedge(int u, int v){    tail->v = v; tail->nxt = last[u]; last[u] = tail++;    tail->v = u; tail->nxt = last[v]; last[v] = tail++;}inline void dfs(int now, int fa){    for (Node *p = last[now]; p; p=p->nxt) if (p->v != fa) dfs(p->v, now);    rep(u, 1, cnt){        dp[now][u] = 1ll;        for (Node *p = last[now]; p; p=p->nxt) if (p->v != fa){            int son = p->v; ll ans = 0;            rep(v, 1, cnt) if (g[lst[u]][lst[v]]) ans += dp[son][v];            dp[now][u] *= ans;        }    }}int main(){    scanf("%d%d", &n, &m);    rep(i, 1, m){        int u, v; scanf("%d%d", &u, &v); g[u][v] = g[v][u] = 1;    }    rep(i, 1, n-1){        int u, v; scanf("%d%d", &u, &v);        addedge(u, v);    }    ll ans = 0;    for (int i = 0; i < (1<<n); i++){        cnt = 0;         rep(j, 1, n) if (!(i&(1<<(j-1)))) lst[++cnt] = j;        dfs(1, 0);        ll res = 0; rep(j, 1, cnt) res += dp[1][j];        if (__builtin_popcount(i)&1) ans -= res; else ans += res;     }    printf("%lld\n", ans);    return 0;    }
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 七个月的宝宝老是拉肚子怎么办 6个月宝宝拉肚子怎么办 没满月宝宝吐奶怎么办 八个月宝宝有点拉肚子怎么办 4个月宝宝拉水怎么办 2岁宝宝消化不好拉肚子怎么办 两岁宝宝老拉肚子怎么办 2岁宝宝拉肚子老不好怎么办 2岁宝宝一直拉肚子不好怎么办 5天新生儿拉稀水怎么办 4天新生儿拉稀水怎么办 新生儿40天拉稀水怎么办 一周多的宝宝拉肚子怎么办 出生半个月的宝宝拉肚子怎么办 刚出生几天的宝宝拉肚子怎么办 刚出生的宝宝拉肚子怎么办 出生八天的宝宝拉肚子怎么办 刚出生婴儿拉水怎么办 三岁宝宝一直吐怎么办 3岁宝宝一直吐怎么办 5个月宝宝一直吐怎么办 新生儿睡反了觉怎么办 吃母乳奶流量大怎么办 两个月宝宝有痰怎么办 婴儿瞌睡睡倒了怎么办 侧切伤口崩开了怎么办 脐带30天未脱落怎么办 洗眉结痂不掉怎么办 新生宝宝生殖器下面破皮怎么办 脐带未脱落渗血怎么办 车停店门口贴发单怎么办 有人要打我我该怎么办 很笨怎么办工作做不好 脸被电焊烤了疼怎么办 脸过敏痒的不行怎么办 领导想让你辞职怎么办 领导强吻我了怎么办 赫曼夏天温度高怎么办 近视看3d电影怎么办 有声挂图撕坏了怎么办 主机没有放光盘的设备怎么办