首页 >> 大全

51Nod-1673-树有几多愁

2023-11-25 大全 27 作者:考证青年

ACM模版

描述

描述

题解

真的感觉这个题好难,看了官方题解也不知道怎么搞,又找了一下代码,稍微懂了一些……总得来说,这个题就是 dp (树归、状压) + 贪心,贴一下官方题解吧……我也说不好。真废……

_愁树是什么树_愁有什么意思

描述

代码

#include 
#include 
#include 
#include 
#include using namespace std;typedef vector<int>::iterator vit;const int MAXN = 1e5 + 10;
const int MAX_LEAF = 20;
const int MOD = 1e9 + 7;int n;
int tot = 0, ans = 1;
int f[MAXN];
int g[1 << MAX_LEAF];
int p[1 << MAX_LEAF];
double h[1 << MAX_LEAF];vector<int> e[MAXN];template <class T>
inline void scan_d(T &ret)
{char c;ret = 0;while ((c = getchar()) < '0' || c > '9');while (c >= '0' && c <= '9'){ret = ret * 10 + (c - '0'), c = getchar();}
}void dfs(int u, int pre)
{for (vit it = e[u].begin(); it != e[u].end(); ++it){int v = *it;if (v == pre){continue;}dfs(v, u);f[u] |= f[v];}if (!f[u]){f[u] = 1 << tot++;}g[f[u]]++;
}int main()
{scan_d(n);int u, v;for(int i = 1; i < n; ++i){scan_d(u), scan_d(v);e[u].push_back(v);e[v].push_back(u);}dfs(1, -1);int tmp;reverse(g, g + (1 << tot));for (int i = 0; i < tot; ++i){tmp = 1 << i;for (int j = 1; j < 1 << tot; ++j){if (j & tmp){g[j] += g[j ^ tmp];}}}reverse(g, g + (1 << tot));for (int i = 0; i < tot; ++i){tmp = 1 << i;for (int j = 1; j < 1 << tot; ++j){if (j & tmp){g[j] = g[j ^ tmp] - g[j];}}}memset(p, -1, sizeof(p));for (int i = 1; i < 1 << tot; ++i){for (int j = 0; j < tot; ++j){tmp = 1 << j;if ((i & tmp) && (p[i] == -1 || h[i] < h[i ^ tmp])){h[i] = h[i ^ tmp];p[i] = j;}}h[i] += log(g[i] + 1);}for (int i = (1 << tot) - 1; i; i ^= 1 << p[i]){ans = ans * (g[i] + 1LL) % MOD;}printf("%d\n", ans);return 0;
}

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了