动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。 
现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种。
有人用两种说法对这N个动物所构成的食物链关系进行描述: 
第一种说法是"1 X Y",表示X和Y是同类。 
第二种说法是"2 X Y",表示X吃Y。 
此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。 
1) 当前的话与前面的某些真的话冲突,就是假话; 
2) 当前的话中X或Y比N大,就是假话; 
3) 当前的话表示X吃X,就是假话。 
你的任务是根据给定的N(1 <= N <= 50,000)和K句话(0 <= K <= 100,000),输出假话的总数。 

Input

第一行是两个整数N和K,以一个空格分隔。 
以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。 
若D=1,则表示X和Y是同类。 
若D=2,则表示X吃Y。

Output

只有一个整数,表示假话的数目。

Sample Input

100 7
1 101 1
2 1 2
2 2 3
2 3 3
1 1 3
2 3 1
1 5 5

Sample Output

3

题解:
首先我们要明确并查集的作用:快速判断两个数是否同一集合与快速合并两个集合成一个集合并求出一些节点之间的关系,
根据的就是树的特点:每个孩子节点有且仅有一个父节点。这样就用数组记录父节点就还(根就记录自己),合并操作就是合并
两个根节点,这儿有个优化就是启发式合并:根记录孩子个数,并把个数少的并到个数大的上面。 
不过我们有其他大招:路径压缩,即我们每次查询的时候都把一条线上的所有节点连接到祖先节点,这样每次查找都很快
(并查集在路径压缩之后的时间复杂度是阿克曼函数)。依据就是我们只需要知道多个孩子节点的祖先是否一致就能判断是否
一个集合,不需要知道树上的结构。我们的权值则是一般记录此节点与父节点的关系,只要满足这个关系可以传递我们就可以模仿矢量计算来处理权值。 
  这儿我们要明确是有三种关系的:两者同类,吃父节点,被父节点吃,所以权值可以用0,1,2表示 
  注意有个关键就是当我们知道x与祖先x1的关系,y与祖先y1的关系,x与y的关系时,求x1与y1的关系时,使用矢量 计算: 
x1->x ->y ->y1 计算
 #include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cstdlib>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#include <queue>
using namespace std;
#define lowbit(x) (x&(-x))
#define max(x,y) (x>y?x:y)
#define min(x,y) (x<y?x:y)
#define MAX 100000000000000000
#define MOD 1000000007
#define pi acos(-1.0)
#define ei exp(1)
#define PI 3.141592653589793238462
#define INF 0x3f3f3f3f3f
#define mem(a) (memset(a,0,sizeof(a)))
typedef long long ll;
ll gcd(ll a,ll b){
return b?gcd(b,a%b):a;
}
bool cmp(int x,int y)
{
return x>y;
}
/*n个动物 k句话 有一种循环a吃b 吃c c吃a 开始不知道n种动物关系是什么
两种询问:d=1 x y为同类 d=2 x吃y 判断假话条数(关键之违背之前的关系)
并查集可以很好解决的满足区间传递关系的区间合并问题,注意一般是多棵树*/
const int N=;
const int mod=1e9+;
int fat[N],ran[N];
void Init(int n)//初始化重要
{
for(int i=; i<=n; i++){
fat[i]=i;//初始化都是指向(看做)自己
ran[i]=;//0同类 1吃父节点 2被父节点吃
}
return;
}
int Find(int x)//找寻父节点+路径压缩
{
if(x==fat[x])
return fat[x];
int y=Find(fat[x]);
ran[x]=(ran[x]+ran[fat[x]])%;//递归后从祖先节点向后到每个孩子来计算
return fat[x]=y;//路径压缩
}
int Union(int typ,int x,int y)//区间并与查询
{
int x1=Find(x);
int y1=Find(y);
if(x1==y1){//共父节点才能判断出关系
if((ran[x]-ran[y]+)%==typ-)
return ;
return ;
}
fat[x1]=y1;//连接两父节点
ran[x1]=(-ran[x]+typ-+ran[y]+)%;//使用类似向量方法来计算权值,虽然题目只有两个,但是会出现被吃这种情况,所以要变成3种情况,注意一定要处理负数的情况
return ;
}
int main()
{
int n,k,ans;
int typ,smt1,smt2;
scanf("%d %d",&n,&k);
Init(n);
ans=;
for(int i=;i<k; i++){
scanf("%d %d %d",&typ,&smt1,&smt2);
if(smt1==smt2&&typ==)
ans++;
else if(smt1>n||smt2>n)
ans++;
else
ans+=Union(typ,smt1,smt2);
}
printf("%d\n",ans);
return ;
}

POJ 1182 食物链 (种类并查集)的更多相关文章

  1. POJ 1182 食物链(种类并查集)

    记得第一次做这道题的时候,推关系感觉有点复杂,而且写完代码后一直WA,始终找不出错误. 在A了十几道并查集后,再做这道题,发现太小儿科了.发现原来之所以WA,就在于查找根节点时,没有同步更新子节点相对 ...

  2. poj 1182 食物链 (并查集)

    http://poj.org/problem?id=1182 关于并查集 很好的一道题,开始也看了一直没懂.这次是因为<挑战程序设计竞赛>书上有讲解看了几遍终于懂了.是一种很好的思路,跟网 ...

  3. POJ 1182 食物链(并查集拆点)

    [题目链接] http://poj.org/problem?id=1182 [题目大意] 草原上有三种物种,分别为A,B,C A吃B,B吃C,C吃A. 1 x y表示x和y是同类,2 x y表示x吃y ...

  4. POJ 1182 食物链(并查集+偏移向量)题解

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

  5. POJ 1182 食物链 (并查集解法)(详细注释)

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

  6. 【POJ 1182 食物链】并查集

    此题按照<挑战程序设计竞赛(第2版)>P89的解法,不容易想到,但想清楚了代码还是比较直观的. 并查集模板(包含了记录高度的rank数组和查询时状态压缩) *; int par[MAX_N ...

  7. 食物链 POJ 1182(种类并查集)

    Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到 ...

  8. POJ 1182 食物链 【并查集】

    解题思路:首先是没有思路的----然后看了几篇解题报告 http://blog.csdn.net/ditian1027/article/details/20804911 http://poj.org/ ...

  9. POJ 1182 食物链 经典并查集+关系向量简单介绍

    题目: 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种. 有 ...

  10. poj 1182食物链(并查集)

    算法思路:把那些确定了相对关系的节点放在同一棵树里(可以同时存在多棵树,单独每棵树中节点的相对关系确定),每个节点对应的 v[] 值记录他与根节点的关系( 0:同类: 1:根吃他: 2:他吃根 ).当 ...

随机推荐

  1. OC通讯录选择封装

    ContactsService.h代码 #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> //block返回选 ...

  2. Jmeter测试实践:文件上传接口

    1.打开jmeter4.0,新建测试计划,添加线程组.根据实际情况配置线程属性. 2.添加HTTP请求. Basic部分修改如下: Advanced部分我做任何修改,完全保持默认.但是有人说Imple ...

  3. 006-优化web请求二-应用缓存、异步调用【Future、ListenableFuture、CompletableFuture】、ETag、WebSocket【SockJS、Stomp】

    四.应用缓存 使用spring应用缓存.使用方式:使用@EnableCache注解激活Spring的缓存功能,需要创建一个CacheManager来处理缓存.如使用一个内存缓存示例 package c ...

  4. PHP数组和字符串的处理函数汇总

    大部分数组处理函数array_chunk — 将一个数组分割成多个array_column — 返回数组中指定的一列array_combine — 创建一个数组,用一个数组的值作为其键名,另一个数组的 ...

  5. (转)redis分布式锁-SETNX实现

    Redis有一系列的命令,特点是以NX结尾,NX是Not eXists的缩写,如SETNX命令就应该理解为:SET if Not eXists.这系列的命令非常有用,这里讲使用SETNX来实现分布式锁 ...

  6. openvpn-LDAP验证

    安装openvpn ldap apt-get install openvpn-auth-ldap mkdir -p /etc/openvpn/auth/ cp /usr/share/doc/openv ...

  7. PHP Fatal error: Uncaught ErrorException: preg_match_all (): JIT compilation failed: no more memory in phar

    PHP 升级到 7.3 后,出现 BUG: 解决办法:修改php.ini文件,;pcre.jit=1 =>  pcre.jit=0

  8. [LeetCode] 111. Minimum Depth of Binary Tree_Easy tag:DFS

    Given a binary tree, find its minimum depth. The minimum depth is the number of nodes along the shor ...

  9. iOS 上传自己的库到cocoapod

    最近自己写了个库,传到github上,想让自己的库支持cocoapod,这里我看了很多相关文章.下面我就写下详细步骤以及会遇到的问题. 我们会使用trunk的方式提交到cocoa pod 这是2014 ...

  10. AM自动化测试平台

    AM自动化测试平台介绍: 最初目标:是为了做接口自动化测试,该平台,集成了,用例管理,测试执行,测试套件(主要为了应对,对场景业务流程有需要的),测试报告展示. 后期目标:适当增加,其它测试工具进行集 ...