思路:

---来源百度

0表示它与根结点为同类,

1表示它吃根结点,

2表示它被根结点吃。

判断两个点a, b的关系,我们令p = Find(a), q = Find(b),即p, q分别为a, b子树的根结点。

1. 如果p != q,说明a, b暂时没有关系,那么关于他们的判断都是正确的,然后合并这两个子树。这里是

关键,如何合并两个子树使得合并后的新树能保证正确呢?这里我们规定只能p合并到q(刚才说过了,启发式合并的优化效果并不那么明显,如果我们用启发式合并,就要推出两个式子,

而这个推式子是件比较累的活...所以一般我们都规定一个子树合到另一个子树)。

那么合并后,p的relation肯定要改变,那么改成多少呢?

这里的方法就是找规律,列出部分可能的情况,就差不多能推出式子了。这里式子为:

tree[p].relation = (tree[b].relation - tree[a].relation + 2 + d) % 3; 这里的d为判断语句中a, b的关系。

还有个问题,我们是否需要遍历整个a子树并更新每个结点的状态呢?

答案是不需要的,因为我们可以在Find()函数稍微修改,即结点x继承它的父亲(注意是前父亲,因为路径压缩后父亲就会改变),

即它会继承到p结点的改变,所以我们不需要每个都遍历过去更新。



2. 如果p = q,说明a, b之前已经有关系了。那么我们就判断语句是否是对的,同样找规律推出式子。

即if ( (tree[b].relation + d + 2) % 3 != tree[a].relation ), 那么这句话就是错误的。



3. 再对Find()函数进行些修改,即在路径压缩前纪录前父亲是谁,

然后路径压缩后,更新该点的状态(通过继承前父亲的状态,这时候前父亲的状态是已经更新的)。

//#include<bits/stdc++.h>
//using namespace std;
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std; const int N=5e4+10;
int pre[N];
int val[N];
int n,m,ans; int Find(int x)
{
if(x==pre[x])
return x;
int tmp=pre[x];
pre[x]=Find(tmp);
val[x]=(val[x]+val[tmp])%3;
return pre[x];
} void Merge(int x,int y,int k)
{
int xx=Find(x);
int yy=Find(y);
if(xx==yy)
{
if(k==2&&(val[y]+k+2)%3!=val[x])
ans++;
if(k==1&&val[x]!=val[y])
ans++;
}
else
{
pre[xx]=yy;
val[xx]=(val[y]-val[x]+2+k)%3;
}
} int main()
{
int temp,x,y;
scanf("%d%d",&n,&m);
ans=0;
for(int i=1;i<=n;i++)
{
pre[i]=i;
val[i]=0;
}
while(m--)
{
scanf("%d%d%d",&temp,&x,&y);
if((x>n||y>n)||(temp==2&&x==y)){
ans++;
continue;
}
Merge(x,y,temp);
}
printf("%d\n",ans);
return 0;
}

然后了解了一下启发式合并,无语。。就是一个智力活。。。

直观感觉就是哪个好我咋合并.

难点就是构造关系(权值):

元素与元素之间关系的转化。

父子结点间关系的转化。

POJ1182【种类并查集】的更多相关文章

  1. NOI2001|POJ1182食物链[种类并查集 向量]

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 65430   Accepted: 19283 Description ...

  2. POJ1182 食物链---(经典种类并查集)

    题目链接:http://poj.org/problem?id=1182   食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submission ...

  3. poj1182(种类并查集好题)

    不得不说,我得感谢@驱动幽灵百鬼夜行小肆,正是因为看明白了他给出的解析,我才完全弄懂种类并查集的,这里,我也不想去改其他的,就直接引用他的解题报告吧 转载:http://blog.csdn.net/c ...

  4. NOIP2010关押罪犯[并查集|二分答案+二分图染色 | 种类并查集]

    题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示 ...

  5. POJ1703Find them, Catch them[种类并查集]

    Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 42416   Accepted: ...

  6. poj1417(种类并查集+dp)

    题目:http://poj.org/problem?id=1417 题意:输入三个数m, p, q 分别表示接下来的输入行数,天使数目,恶魔数目: 接下来m行输入形如x, y, ch,ch为yes表示 ...

  7. poj1733(种类并查集+离散化)

    题目链接: http://poj.org/problem?id=1733 题意: 输入n表示有一个长度为n的0,1字符串, m表示接下来有m行输入, 接下来的m行输入中x, y, even表示第x到第 ...

  8. poj 1182:食物链(种类并查集,食物链问题)

    食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 44168   Accepted: 12878 Description ...

  9. pku 1703(种类并查集)

    题目链接:http://poj.org/problem?id=1703 思路;个人觉得本质上还是和带权并查集一样的,只不过多了一个MOD操作,然后就是向量关系图稍微改动一下就变成种类并查集了,对于本题 ...

  10. hdu 3038 How Many Answers Are Wrong(种类并查集)2009 Multi-University Training Contest 13

    了解了种类并查集,同时还知道了一个小技巧,这道题就比较容易了. 其实这是我碰到的第一道种类并查集,实在不会,只好看着别人的代码写.最后半懂不懂的写完了.然后又和别人的代码进行比较,还是不懂,但还是交了 ...

随机推荐

  1. 公网RTSP地址(持续更新)

    H264+AAC: rtsp://a2047.v1412b.c1412.g.vq.akamaistream.net/5/2047/1412/1_h264_350/1a1a1ae555c53196016 ...

  2. npm ERR! Unexpected end of JSON input while parsing near '...inimist":"^1.2.0"}

    简介 在项目中执行npm install安装依赖包的时候.出现npm ERR! Unexpected end of JSON input while parsing near '...inimist& ...

  3. 解决Error:Unable to find method 'org.gradle.api.internal.project.ProjectInternal.

    错误描述今天在Github上面下载了一份代码,然后导入到Android Studio中直接报错误 错误描述如下: Error: Unable to find method ‘org.gradle.ap ...

  4. Gym - 100187J J - Deck Shuffling —— dfs

    题目链接:http://codeforces.com/gym/100187/problem/J 题目链接:问通过洗牌器,能否将编号为x的牌子转移到第一个位置? 根据 洗牌器,我们可以知道原本在第i位置 ...

  5. weixin报警脚本

    #!/bin/bash ### script name weixin.sh ### send messages from weixin for zabbix monitor ### jack ### ...

  6. ffmpeg 的一些学习网站

    http://blog.csdn.net/leixiaohua1020/article/category/1360795 雷霄骅(leixiaohua1020)的专栏 http://dranger.c ...

  7. JSR 303 - Bean Validation 是什么?

    关于 Bean Validation JSR 303 - Bean Validation 是jree6 中的一项子规范,JSR 303 - Bean Validation着重解决以下实际问题: 在任何 ...

  8. C语言 写的 表达式求值。

    有不对的地方还望指出来,让我改正.谢谢.存一个代码 #include<stdio.h> #include<stdlib.h> #include<string.h> ...

  9. python中通过xlwt、xlrd和xlutils操作xls

    xlwt模块用于在内存中生成一个xls/xlsx对象,增加表格数据,并把内存中的xls对象保存为本地磁盘xls文件; xlrd模块用于把本地xls文件加载到内存中,可以读取xls文件的表格数据,查询x ...

  10. Mac的环境变量

    在终端输入: vim ~/.bash_profile 按i切换到INSERT模式.然后把路径按照下面的格式写进去.然后输入:wq保存退出. export PATH=${PATH}:/Users/Dru ...