Jumping Monkey 并查集,反向思维
题意 :
- n点的树,每个点的点权distinct,求分别从每个点出发能到达的点数(被到达的点必须是路径上点权最大的点)
思路 :
- 考虑点权最大的那个结点(假设为u),显然不管从哪个结点开始跳一次,都可以跳到u,且不能越过u,也就是说到达u后不能跳到其它点,于是u一定是最优方案中最后一个到达的点。我们将结点u以及它相连的边从树上去掉,对剩下的每个连通块递归进行上述过程即可获得答案。
- 但要实现上述递归过程并不容易,转而反向思考这个过程,按点权从小到大枚举结点u,并将u作为所有与u相连的(已经枚举过的)连通块的根(用并查集维护,只连一个点可以将复杂度从O(n)降到O(logn))从而建立一颗新树,每个结点的深度(根深度为1)即是答案
#include <iostream>
#include <cstring>
#include <map>
#include <vector>using namespace std;const int N = 1e5 + 10;vector<int> G[N], G2[N];
int fa[N];
bool st[N];
int c[N], a[N];
map<int, int> dc;void init(int n)
{for (int i = 1; i <= n; i ++ )fa[i] = i;
}int find(int x)
{if (fa[x] != x) fa[x] = find(fa[x]);return fa[x];
}void merge(int a, int b)
{a = find(a), b = find(b);if (a != b) fa[a] = b;
}// 求点的深度
void dfs(int u)
{for (auto v : G2[u]){a[v] = a[u] + 1;dfs(v);}
}int main()
{ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);int T;cin >> T;while (T -- ){int n;cin >> n;// 并查集初始化init(n);// 多组数据for (int i = 1; i <= n; i ++ ) G[i].clear(), G2[i].clear();memset(st, 0, sizeof st);dc.clear();// 树,无向图,注意是n - 1条边!!!for (int i = 0; i < n - 1; i ++ ){int u, v;cin >> u >> v;G[u].push_back(v);G[v].push_back(u);}// map 点权-点编号for (int i = 1; i <= n; i ++ ){cin >> c[i];dc[c[i]] = i;}st[dc.begin() -> second] = true; // 点权值最小的点为根,第一个访问for (auto it = ++ dc.begin(); it != dc.end(); it ++ ){auto u = it -> second;for (auto v : G[u]) // 原图中相连的点{if (!st[v]) continue; // 已经枚举过的连通块int cc = find(v);merge(v, u); // 将已经枚举过的连通块的根接在u下G2[u].push_back(cc);}st[u] = true; // 已经访问过u}int x = ( -- dc.end()) -> second;a[x] = 1;dfs(x);for (int i = 1; i <= n; i ++ ) cout << a[i] << endl;}return 0;
}
Jumping Monkey 并查集,反向思维相关推荐
- 2021中国大学生程序设计竞赛(CCPC)- 网络选拔赛(重赛) Jumping Monkey(并查集,逆向考虑)
LINK 考虑权值最大的节点为 z z z,那么其他所有点最后都是跳到这个点,且不能越过这个点到其他点 那么其实我们可以把所有其他节点的答案都加 1 1 1,相当于把 z z z删掉,分成若干个连通块 ...
- hdu 3234 Exclusive-OR 题解(并查集,思维)
该死的期末复习终于结束了... 暑假来了\color{#ff0000}{暑假来了}暑假来了!!! 所以我就珂以非常开心的写博客了. 原题链接: hdu 题意简述 多组数据.你有一个没有确定的数列.有一 ...
- upc-WNJXYK and DIDIDI and monkey(并查集启发式合并)
题目描述 DIDIDI and WNJXYK are good friends. One day, they go to the zoo. The monkeys are playing happil ...
- 【CodeForces - 1131F 】Asya And Kittens(并查集,思维)
题干: Asya loves animals very much. Recently, she purchased nn kittens, enumerated them from 11 and nn ...
- 【CodeForces - 731C】Socks(并查集,思维)
题干: Arseniy is already grown-up and independent. His mother decided to leave him alone for m days an ...
- 【Nowcoder】2020牛客暑期多校训练营(第八场)I - Interesting Computer Game | 并查集、思维、离散化
题目链接:https://ac.nowcoder.com/acm/contest/5673/I 题目大意: 从1~n给出n组数据,每次可以选择a 或者选择b,选了之后不能在选,问最多选多少个? 题目思 ...
- 【CodeForces - 278C 】Learning Languages(并查集,思维)
题干: The "BerCorp" company has got n employees. These employees can use m approved official ...
- 中石油训练赛 - 奎奎画画(思维+并查集+离线处理)
题目描述 "为你写诗,为你静止,为你做不可能的事",爱情是一种怪事,它让奎奎开始学习画画.奎奎认为一张画的艺术价值等于画上的白色联通块个数(当一个格子和它上下左右四个方向上的某个相 ...
- CodeForces - 468B Two Sets(并查集+思维)
题目链接:点击查看 题目大意:现在给出两个集合A和B,再给出两个数a和b,现在规定在集合A中的数x必须满足x和a-x同时在集合a中,而在集合B中的数x也同样需要满足x和b-x同时在集合B中,现在给出一 ...
最新文章
- 2_2 递归与分治策略(分治法的基本思想)
- 手把手教你学Vue-3(路由)
- 一个不错的windows编程网址
- 一篇文章带你从认识Python装饰器到熟练使用
- P2678 [NOIP2015 提高组] 跳石头
- Android应用开发—FragmentManager如何管理fragments
- 重磅!尤雨溪公布 Vue 3.0 开发路线
- 孙丕恕:应把云计算大数据融在一起 降低社会运营成本
- 【Office Word】论文排版有关技巧
- jquery中如何获得$.ajax()事件返回的值
- python sep参数_Python 3.3:分离参数(sep)给出
- 程序中try、throw、catch三者之间的关系
- 详解Python中re.sub
- pdf阅读,保存上次阅读位置
- 合与荣—— 惠普融合战略的深化与落地
- 隐马尔科夫链HMM详解
- win10使用软件提示“为了对电脑进行保护,已经阻止此应用”或软件上面有盾牌不能正常打开软件。
- (第六章)hive之查询
- ESP8266通过arduino IED连接巴法云(TCP创客云)
- python递归编程题_Python数据结构与算法41:递归编程练习题4:铺瓷砖
热门文章
- 物料Bapi默认采购价值代码
- 9个妙招增强家庭WIFI信号
- SAP推出iPhone手机端企业智能管理应用
- CL_GUI_PICTURE
- ABAP程序中调用不同类型的函数弹出不同的消息对话框
- 检查用户是否有权限从ABAP里调用C kernel functions
- 选对工具,你也能做出别人家的酷炫大屏
- 手里的基金在震荡?数据解读2021“开门红”如何控制仓位
- 从Q4财报,看有道如何实现从在线教育“迷途”中脱身?
- android 窗口监听按键,Android编程实现Dialog窗体监听的方法