当前位置: 首页 > news >正文

并查集——向量偏移

让我们用一道题来说明这个问题吧

题目连接:http://poj.org/problem?id=1182

我们先不妨假设a与b是同类的时候偏移量为0

a吃b的时候偏移量1

a被b吃的时候偏移量为2   a的父亲节点为aa b的父亲节点为bb

有了这个假设,那下面就能很方便解决这个问题了

我们先查找给出节点的父亲节点然后看看父亲节点的是不是相同的 如果是不相同的那么我们就更新b的父亲节点的偏移量 

先看一张图片

由图片可知   p[fx].relation = (3 + p[y].relation - p[x].relation + d - 1) % 3;   对3取余是为了让他在1 和2之间-p[x].relation表示从x到x的父节点的偏移量d-1是x到y的偏移量p.relation表示偏移量

如果父节点相同的话 那我们就检验两个节点的关系是否与给出的d相同

如果相同就continue 如果不同就让假话次数+1

总结:

向量偏移其实就是并查集的变形,但是他有一个局限性 局限于种类少的题目 这样才能用向量偏移

其实向量偏移就是在初始化的时候给数组加一个属性   就是偏移量,然后去更新这些偏移量来判断是否正确

这两张图片看懂了就能明白向量偏移了

下面看代码:

#include<stdio.h>
#include<math.h>
#include<string.h>
#include<algorithm>
#include<iostream>

using namespace std;

struct node
{
    int bin;
    int relation;
}p[50005];

int findx(int x)

{
    int t;
    if(p[x].bin == x)return x;
    else
    {
        t = p[x].bin;
        p[x].bin = findx(t);
        p[x].relation = (p[x].relation + p[t].relation) % 3; //更新x对根的偏移量
    }
    return p[x].bin;
}

void join(int x,int y,int fx,int fy,int d)

{
    p[fx].bin = fy;
    p[fx].relation = (3 + p[y].relation - p[x].relation + d - 1) % 3; //更新x根的偏移量
    //   画图可知  x的根的偏移量为这个公式
}

int main()

{
    int n,k,d,x,y,fx,fy,i,sum;
    scanf("%d%d",&n,&k);
    for(i = 1;i <= n;i++)
    {
        p[i].bin = i;
        p[i].relation = 0;
    }
    sum = 0;
    while(k--)
    {
        scanf("%d%d%d",&d,&x,&y);
        fx = findx(x);
        fy = findx(y);
        if(x > n|| y > n||(d == 2&& x == y))sum++;
        else
        {
            if(fx != fy)
            join(x,y,fx,fy,d);
            else   //如果跟节点相同就判断两个点与跟的关系
            {
                if(d == 1&&p[x].relation != p[y].relation)
                    sum++;
                else if(d == 2&&(p[x].relation - p[y].relation + 3) % 3 != 1)
                    sum++;
            }
        }
    }
    printf("%d\n",sum);

}

 

转载于:https://www.cnblogs.com/zhanyage110/p/4394716.html

相关文章:

  • 洛谷P3952 时间复杂度
  • XSS Filter Evasion Cheat Sheet 中文版
  • 【Android Studio安装部署系列】二十七、Android studio修改项目名称和包名
  • awk编程
  • 24. 两两交换链表中的节点
  • 如何使Python完美升级到新版本
  • 子集
  • 源码编译安装LNMP环境及配置基于域名访问的多虚拟主机
  • Linux各目录及每个目录的详细介绍
  • 90分 蓝桥杯 算法提高 道路和航路 [ 最短路 ]
  • linux一次卸载多个软件
  • 《大话数据结构》读书笔记(一)
  • Tyvj3632|超级英雄Hero
  • 如何从mysql数据库中取到随机的记录
  • soapUI使用-DataSource获取oracle库中的参数
  • Computed property XXX was assigned to but it has no setter
  • HashMap剖析之内部结构
  • java 多线程基础, 我觉得还是有必要看看的
  • JS进阶 - JS 、JS-Web-API与DOM、BOM
  • Nacos系列:Nacos的Java SDK使用
  • Node 版本管理
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • Python十分钟制作属于你自己的个性logo
  • Python实现BT种子转化为磁力链接【实战】
  • 基于axios的vue插件,让http请求更简单
  • 记一次删除Git记录中的大文件的过程
  • 看域名解析域名安全对SEO的影响
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 深入浅出Node.js
  • 无服务器化是企业 IT 架构的未来吗?
  • 移动端唤起键盘时取消position:fixed定位
  • 应用生命周期终极 DevOps 工具包
  • 主流的CSS水平和垂直居中技术大全
  • 最近的计划
  • ionic异常记录
  • 国内唯一,阿里云入选全球区块链云服务报告,领先AWS、Google ...
  • 如何正确理解,内页权重高于首页?
  • ​LeetCode解法汇总518. 零钱兑换 II
  • ​用户画像从0到100的构建思路
  • #QT(一种朴素的计算器实现方法)
  • (html转换)StringEscapeUtils类的转义与反转义方法
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (分布式缓存)Redis哨兵
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (全部习题答案)研究生英语读写教程基础级教师用书PDF|| 研究生英语读写教程提高级教师用书PDF
  • (实战)静默dbca安装创建数据库 --参数说明+举例
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (转)scrum常见工具列表
  • (转载)PyTorch代码规范最佳实践和样式指南
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .NET连接MongoDB数据库实例教程
  • .NET序列化 serializable,反序列化
  • /etc/fstab 只读无法修改的解决办法