ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[AcWing 240] && P2024 [NOI2001] 食物链

2022-05-03 00:35:02  阅读:188  来源: 互联网

标签:P2024 int px py 距离 find 240 && 节点


image
image


点击查看代码
#include<iostream>

using namespace std;
const int N = 5e5 + 10;
int p[N], d[N];
int find(int x)
{
    if (p[x] != x) {
        int u = find(p[x]);
        d[x] += d[p[x]];
        p[x] = u;
    }
    return p[x];
}
int main()
{
    int n, k;
    cin >> n >> k;
    for (int i = 1; i <= n; i ++)   p[i] = i;
    int res = 0;
    while (k --) {
        int t, x, y;
        scanf("%d %d %d", &t, &x, &y);
        if (x > n || y > n) res ++;
        else {
            int px = find(x), py = find(y);
            if (t == 1) {
                if (px == py && (d[x] - d[y]) % 3)  res ++;
                else if (px != py) {
                    p[px] = py;
                    d[px] = d[y] - d[x];
                }
            }
            else {
                if (px == py && (d[x] - d[y] - 1) % 3)  res ++;
                else if (px != py) {
                    p[px] = py;
                    d[px] = d[y] + 1 - d[x];
                }
            }
        }
    }
    cout << res;
    return 0;
}

  1. 维护一个并查集的同时,记录每个节点到根节点的距离,距离为 1 表示可以吃根节点,距离为 2 表示可以被根节点吃,距离为 3 表示和根节点是同类;
  2. 距离的更新在 find 中完成,u = find( p[ x ] ) 有两个作用,一个是记录根节点,一个是更新 p[ x ] 后面节点到根节点的距离,执行完这条语句后,d[ p[ x ] ] 就是 p[ x ] 到根节点的距离;
  3. res ++ 有 3 种情况:
    ① x > n 或者 y > n,违背了条件 2;
    ② t == 1,x 和 y 同属于一个集合,但是 d[ x ] % 3 和 d[ y ] % 3 的值不同,也就是 (d[ x ] - d[ y ]) % 3 != 0,那么根据距离的意义,x 和 y 与根节点的关系必不相同,从而推出 x 和 y 必不是同类,与 t == 1 表示 x 和 y 是同类矛盾,违背了条件 1;
    ③ t == 0,x 和 y 属于同一个集合,若要 x 吃 y,根据题目条件,只有 a 吃 b,b 吃 c 时,可以推出 c 吃 a,那么要想让 x 吃 y,则要让 y 吃根节点,根节点吃 x,那么就可以推出 x 吃 y,在这种条件下,d[ x ] 和 d[ y ] 需要满足一定的条件,y 吃根节点,说明 d[ y ] % 3 == 1,x 被根节点吃,说明 d[ x ] % 3 == 2,也就是 (d[ x ] - d[ y ] - 1) % 3 == 0,那么如果 (d[ x ] - d[ y ] - 1) % 3 != 0,就肯定没有 x 吃 y,与 t == 0 表示 x 吃 y 矛盾,违背了条件 1;(x 吃 x 可以看作是 x 吃 y,当 y = x 时的特例,同时也违背了条件 3)
  4. 需要合并并查集的 2 种情况:
    ① t == 1,x 和 y 不属于同一个集合,让 x 的根节点作为 y 的根节点的孩子节点,需要让 d[ px ] 取一定的值,满足 t == 1 时,x 和 y 同类这个条件,此时,x 到 y 的根节点的距离为 d[ x ] + d[ px ],y 到 y 的根节点的距离为 d[ y ],两个距离 % 3 的值应该相同,取一种简单的情况,两个距离相等,由 d[ x ] + d[ px ] = d[ y ] 可以推出 d[ px ] = d[ y ] - d[ x ];
    ② t == 0,x 和 y 不属于同一个集合,让 x 的根节点作为 y 的根节点的孩子节点,需要让 d[ px ] 取一定的值,满足 t == 0 时,x 吃 y 这个条件,此时,x 到 y 的根节点的距离为 d[ x ] + d[ px ],y 到 y 的根节点的距离为 d[ y ],x 的这个距离应当 % 3 = 2,y 的这个距离应当 % 3 = 1,取一种简单的情况,让两个距离的差值为 1,由 d[ x ] + d[ px ] - d[ y ] = 1 可以推出 d[ px ] = d[ y ] + 1 - d[ x ];

标签:P2024,int,px,py,距离,find,240,&&,节点
来源: https://www.cnblogs.com/wKingYu/p/16217439.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有