51Nod-1322-关于树的函数
来源:互联网 发布:数据库resource权限 编辑:程序博客网 时间:2024/06/13 01:44
ACM模版
描述
题解
典型的树归问题,复杂度
暂且不说树归部分,我们先考虑任何一种状态下如何求
假如 A1 集合中有 n 个结点,那么 A2 集合中有 N - n 个结点。假如 B1 集合中有 m 个结点,那么 B2 集合中有 N-m 个结点。
假如 A1 与 B1 交集有 cnt 个结点,那么 A1 与 B2 交集有 n-cnt 个结点,那么 A2 与 B1 交集有 m-cnt 个结点,那么 A2 与 B2 交集有 N-m-n+cnt 个结点。
假如……那么……没了,这个部分就这样!
接着就是树归部分,如何枚举出所有情况?首先我们可以对 Tree1 的一个子树进行 dfs(),标记为集合 A1,然后在这个状态下对 Tree2 进行 dfs_(),这个部分就切切实实是树归了,在回溯的过程中进行上述规则的计数累加即可。
具体的还是要分析代码,理解了树归也就不难看懂代码了。
这里利用了 tuple 容器,如果不用这个容器就需要用到结构体指针了,毕竟 dfs_() 过程中要返回两个值,分别是 cnt 和 m。
代码
#include <iostream>#include <algorithm>#include <cstring>#include <vector>#include <set>#include <tuple>using namespace std;typedef long long ll;typedef tuple<int, int> tii;const int MAXN = 4e3 + 10;int N;int n; // A1集合结点数ll res = 0;vector<int> tree[MAXN];vector<int> tree_[MAXN];tii tmp;struct edge{ int u; int v;} tr[MAXN], tr_[MAXN];int vis[MAXN];tii dfs_(int last, int root){ int cnt = 0, m = 0; if (vis[root]) { cnt++; } m++; int a, b; for (int i = 0; i < tree_[root].size(); i++) { if (tree_[root][i] != last) { tmp = dfs_(root, tree_[root][i]); tie(a, b) = tmp; cnt += a; m += b; } } if (m == N) { return make_tuple(cnt, m); } long long maxRes = 0; maxRes = max(maxRes, (ll)cnt * cnt); maxRes = max(maxRes, (ll)(n - cnt) * (n - cnt)); maxRes = max(maxRes, (ll)(m - cnt) * (m - cnt)); maxRes = max(maxRes, (ll)(N - m - n + cnt) * (N - m - n + cnt)); res += maxRes; return make_tuple(cnt, m);}void dfs(int last, int root){ vis[root] = 1; n++; for (int i = 0; i < tree[root].size(); i++) { if (tree[root][i] != last) { dfs(root, tree[root][i]); } }}int main(int argc, const char * argv[]){// freopen("/Users/zyj/Desktop/input.txt", "r", stdin); cin >> N; int u, v; for (int i = 1; i < N; i++) { scanf("%d%d", &u, &v); u++, v++; tree[u].push_back(v); tree[v].push_back(u); tr[i].u = u; tr[i].v = v; } for (int i = 1; i < N; i++) { scanf("%d%d", &u, &v); u++, v++; tree_[u].push_back(v); tree_[v].push_back(u); tr_[i].u = u; tr_[i].v = v; } for (int i = 1; i < N; i++) { n = 0; memset(vis, 0, sizeof(vis)); dfs(tr[i].v, tr[i].u); dfs_(-1, 1); } cout << res << '\n'; return 0;}
0 0
- 51Nod-1322-关于树的函数
- 51nod 1829 函数
- 51Nod-1829-函数
- 【51Nod 1379】索函数
- 51nod-1379 索函数
- 51nod 1379 索函数
- 51Nod-1379-索函数
- 关于逆元的概念、用途和可行性的思考(附51nod 1013 和 51nod 1256)
- 51nod 1405 树的距离之和
- 51nod 1405 树的距离之和
- 51nod-1412 AVL树的种类
- [51nod 1801]wangyuzree的树
- [51nod 1412]AVL树的种类
- 51nod-1405 树的距离之和
- 51nod 1405 树的距离之和
- 51nod 1412 AVL树的种类
- 51nod 1737 配对【树的重心】
- 51nod 1737【树的重心】
- 杨辉三角
- 极光推送开发第二弹——极光推送API
- Ubuntu根目录结构说明
- Java8:Stream
- C语言练习
- 51Nod-1322-关于树的函数
- 计算数据的相似度:欧几里德、皮尔逊相关度
- 四种分页的写法--4月27号
- 【Git】简单使用方法
- 程序员:像机器一样思考
- 信息的表示和处理(待补充)
- 即拿即用-选择头像,可以选择相册,拍照,查看大图,保存到本地
- spring10
- 端游、手游服务端常用的架构是什么样的?