题意 :

  • 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 并查集,反向思维相关推荐

  1. 2021中国大学生程序设计竞赛(CCPC)- 网络选拔赛(重赛) Jumping Monkey(并查集,逆向考虑)

    LINK 考虑权值最大的节点为 z z z,那么其他所有点最后都是跳到这个点,且不能越过这个点到其他点 那么其实我们可以把所有其他节点的答案都加 1 1 1,相当于把 z z z删掉,分成若干个连通块 ...

  2. hdu 3234 Exclusive-OR 题解(并查集,思维)

    该死的期末复习终于结束了... 暑假来了\color{#ff0000}{暑假来了}暑假来了!!! 所以我就珂以非常开心的写博客了. 原题链接: hdu 题意简述 多组数据.你有一个没有确定的数列.有一 ...

  3. upc-WNJXYK and DIDIDI and monkey(并查集启发式合并)

    题目描述 DIDIDI and WNJXYK are good friends. One day, they go to the zoo. The monkeys are playing happil ...

  4. 【CodeForces - 1131F 】Asya And Kittens(并查集,思维)

    题干: Asya loves animals very much. Recently, she purchased nn kittens, enumerated them from 11 and nn ...

  5. 【CodeForces - 731C】Socks(并查集,思维)

    题干: Arseniy is already grown-up and independent. His mother decided to leave him alone for m days an ...

  6. 【Nowcoder】2020牛客暑期多校训练营(第八场)I - Interesting Computer Game | 并查集、思维、离散化

    题目链接:https://ac.nowcoder.com/acm/contest/5673/I 题目大意: 从1~n给出n组数据,每次可以选择a 或者选择b,选了之后不能在选,问最多选多少个? 题目思 ...

  7. 【CodeForces - 278C 】Learning Languages(并查集,思维)

    题干: The "BerCorp" company has got n employees. These employees can use m approved official ...

  8. 中石油训练赛 - 奎奎画画(思维+并查集+离线处理)

    题目描述 "为你写诗,为你静止,为你做不可能的事",爱情是一种怪事,它让奎奎开始学习画画.奎奎认为一张画的艺术价值等于画上的白色联通块个数(当一个格子和它上下左右四个方向上的某个相 ...

  9. CodeForces - 468B Two Sets(并查集+思维)

    题目链接:点击查看 题目大意:现在给出两个集合A和B,再给出两个数a和b,现在规定在集合A中的数x必须满足x和a-x同时在集合a中,而在集合B中的数x也同样需要满足x和b-x同时在集合B中,现在给出一 ...

最新文章

  1. 2_2 递归与分治策略(分治法的基本思想)
  2. 手把手教你学Vue-3(路由)
  3. 一个不错的windows编程网址
  4. 一篇文章带你从认识Python装饰器到熟练使用
  5. P2678 [NOIP2015 提高组] 跳石头
  6. Android应用开发—FragmentManager如何管理fragments
  7. 重磅!尤雨溪公布 Vue 3.0 开发路线
  8. 孙丕恕:应把云计算大数据融在一起 降低社会运营成本
  9. 【Office Word】论文排版有关技巧
  10. jquery中如何获得$.ajax()事件返回的值
  11. python sep参数_Python 3.3:分离参数(sep)给出
  12. 程序中try、throw、catch三者之间的关系
  13. 详解Python中re.sub
  14. pdf阅读,保存上次阅读位置
  15. 合与荣—— 惠普融合战略的深化与落地
  16. 隐马尔科夫链HMM详解
  17. win10使用软件提示“为了对电脑进行保护,已经阻止此应用”或软件上面有盾牌不能正常打开软件。
  18. (第六章)hive之查询
  19. ESP8266通过arduino IED连接巴法云(TCP创客云)
  20. python递归编程题_Python数据结构与算法41:递归编程练习题4:铺瓷砖

热门文章

  1. 物料Bapi默认采购价值代码
  2. 9个妙招增强家庭WIFI信号
  3. SAP推出iPhone手机端企业智能管理应用
  4. CL_GUI_PICTURE
  5. ABAP程序中调用不同类型的函数弹出不同的消息对话框
  6. 检查用户是否有权限从ABAP里调用C kernel functions
  7. 选对工具,你也能做出别人家的酷炫大屏
  8. 手里的基金在震荡?数据解读2021“开门红”如何控制仓位
  9. 从Q4财报,看有道如何实现从在线教育“迷途”中脱身?
  10. android 窗口监听按键,Android编程实现Dialog窗体监听的方法