Description

动物王国中有三类动物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

只有一个整数,表示假话的数目。
我是 比如 A>B>C 对于每个点都有 P[X] V[X]表示 他被谁打败了  他打败了谁   他们之间的关系处理好后 比如A>B>C D>E>F  一旦 B 与E有关系 在不出错的前提下 然后 处理好 AD  BE CF之间的关系 
#include <iostream>
#include<cstdio>
#include<string.h>
using namespace std;
const int maxn=;
int per[maxn],p[maxn],v[maxn],N,K;
int fa(int a){ return per[a]=per[a]==a?a:fa(per[a]);}
bool jud1(int X,int Y){
if(X<||Y<||X>N||Y>N) return false;
int fx=fa(X),fy=fa(Y);
if(fx==p[fy]||fx==v[fy]||fy==p[fx]||fy==v[fx]) return false;
per[fy]=fx;
if(p[fx]!=&&p[fy]!=){ per[p[fy]]=p[fx];}
if(p[fx]==&&p[fy]!=)p[fx]=p[fy];
if(v[fx]!=&&v[fy]!=){ per[v[fy]]=v[fx];}
if(v[fx]==&&v[fy]!=) v[fx]=v[fy];
if(p[fx]!=){ p[p[fx]]=v[fx]; v[p[fx]]=fx; }
if(v[fx]!=){ p[v[fx]]=fx; v[v[fx]]=p[fx];}
return true;
}
bool jud2(int X,int Y){
if(X<||Y<||X>N||Y>N) return false;
int fx=fa(X),fy=fa(Y);
if(fx==fy||fx==v[fy]||fy==p[fx]) return false;
if(p[fy]!=)per[p[fy]]=fx;
if(v[fx]==)v[fx]=fy;
else per[fy]=v[fx];
if(p[fx]!=&&v[fy]!=) per[v[fy]]=p[fx];
if(p[fx]==&&v[fy]!=) p[fx]=v[fy];
if(p[fx]!=){ v[p[fx]]=fx;p[p[fx]]=v[fx];}
if(v[fx]!=){ p[v[fx]]=fx;v[v[fx]]=p[fx];} return true;
}
int main()
{
scanf("%d%d",&N,&K);
for(int i=;i<=N;i++){
per[i]=i; p[i]=v[i]=;
}
int num=;
for(int i=;i<K;i++){
int D,X,Y;
scanf("%d%d%d",&D,&X,&Y);
switch(D){
case : if(jud1(X,Y)==false) ++num; break;
case : if(jud2(X,Y)==false) ++num; break;
}
}
cout<<num<<endl; return ;
}

还有一种方法 带权并查集 队友说也可以

当 操作1 时 判断

1 这两个点在 同一个集合当中  他们到达 祖先的距离不同则出现错误 相同就正确

2 这两个点不在同一个集合当中 那么就得将这两个集合 合并 就是说 d[x]=(d[y]+d[fy])%3或者 d[y]=(d[x]+d[fx])%3 这样就保证了他们在一个集合当中的相同的位置 我们在并查集中做了一点小动作 保证了要修改的 d[fx] 或者d[fy] 为跟节点的子树 能够将相应的位置进行相应的改变

当操作2 时 判断

1 这两个的点在同一个集合当中 他们到达祖先的距离(d[x]+1)必须等于d[y] 否则就出现错误(因为我们保证了小的距离吃大的距离 自然最后记得模三)

2 这两个点在不懂得集合当中 那么也必须得河滨这两个集合 就是说 (d[x]+1)%3==(d[y]+d[fy])%3 可以推得 (d[x]+1-d[y]+3)==d[fy] 这样也保证了这两个点在相对的位置

#include <iostream>
#include<cstdio>
#include<string.h>
using namespace std;
const int maxn=;
int per[maxn],d[maxn];
int fin(int a){
if(per[a]==a)return a;
int t=per[a];
per[a]=fin(per[a]);
d[a]=(d[a]+d[t])%;
return per[a];
}
bool unionnode(int D,int x,int y){
int fx=fin(x),fy=fin(y);
if(D==){
if(fx==fy){ return d[x]==d[y]?true:false; }
if(d[x]==d[y]){ per[fy]=fx;return true;}
if(d[x]>d[y]){ d[fy]=(d[x]-d[y])%;per[fy]=fx; return true; }
d[fx]=(d[y]-d[x])%; per[fx]=fy; return true;
}
if(fx==fy){ return ((d[x]+)%)==d[y]?true:false; }
d[fy]=(d[x]-d[y]++)%;
per[fy]=fx;
return true;
}
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++){
per[i]=i;d[i]=;
}
int num=;
while(k--){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(b>n||c>n||!unionnode(a,b,c)) num++;
}
printf("%d\n",num);
return ;
}

POJ 1182 并查集的更多相关文章

  1. POJ1703 && POJ2942 &&POJ 1182 并查集 这个做法挺巧妙

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

  2. 食物链 POJ - 1182 (并查集的两种写法)

    这是一个非常经典的带权并查集,有两种写法. 1 边权并查集 规定一下,当x和y这条边的权值为0时,表示x和y是同类,当为1时,表示x吃y,当为2时,表示x被y吃. 一共有三种状态,如图,当A吃B,B吃 ...

  3. poj 1182 并查集高级应用

    C - 是谁站在食物链的顶端 Crawling in process... Crawling failed Time Limit:1000MS     Memory Limit:10000KB     ...

  4. poj 1984 并查集

    题目意思是一个图中,只有上下左右四个方向的边.给出这样的一些边, 求任意指定的2个节点之间的距离. 就是看不懂,怎么破 /* POJ 1984 并查集 */ #include <stdio.h& ...

  5. poj 1797(并查集)

    http://poj.org/problem?id=1797 题意:就是从第一个城市运货到第n个城市,最多可以一次运多少货. 输入的意思分别为从哪个城市到哪个城市,以及这条路最多可以运多少货物. 思路 ...

  6. POJ 2492 并查集扩展(判断同性恋问题)

    G - A Bug's Life Time Limit:10000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u S ...

  7. POJ 2492 并查集应用的扩展

    A Bug's Life Time Limit: 10000MS Memory Limit: 65536K Total Submissions: 28651 Accepted: 9331 Descri ...

  8. POJ 3228 [并查集]

    题目链接:[http://poj.org/problem?id=3228] 题意:给出n个村庄,每个村庄有金矿和仓库,然后给出m条边连接着这个村子.问题是把所有的金矿都移动到仓库里所要经过的路径的最大 ...

  9. poj 1733 并查集+hashmap

    题意:题目:有一个长度 已知的01串,给出多个条件,[l,r]这个区间中1的个数是奇数还是偶数,问前几个是正确的,没有矛盾 链接:点我 解题思路:hash离散化+并查集 首先我们不考虑离散化:s[x] ...

随机推荐

  1. iOS 禁止手势滑动翻页

    - (void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; // 禁用 iOS7 返回手势 if ([self.navi ...

  2. spark 将dataframe数据写入Hive分区表

    从spark1.2 到spark1.3,spark SQL中的SchemaRDD变为了DataFrame,DataFrame相对于SchemaRDD有了较大改变,同时提供了更多好用且方便的API.Da ...

  3. CSS 盒子模型 二

    Sublime 快捷键: 文件保存后,输入 html:xt + tab  ,补全html html:xt <!DOCTYPE html PUBLIC "-//W3C//DTD XHTM ...

  4. Android系统dimension单位详解

    转载请注明出处,谢谢!http://www.cnblogs.com/coding-way/p/3457878.html Android设备种类多样,要想适配好各种屏幕,理解各种屏幕数据是必须的.首先先 ...

  5. sklearn的快速使用

    传统的机器学习任务从开始到建模的一般流程是:获取数据 -> 数据预处理 -> 训练建模 -> 模型评估 -> 预测,分类.本文我们将依据传统机器学习的流程,看看在每一步流程中都 ...

  6. DLRS(近三年深度学习应用于推荐系统论文汇总)

    Recommender Systems with Deep Learning Improving Scalability of Personalized Recommendation Systems ...

  7. ELK之nginx日志使用json格式输出

    json Nginx默认日志输出格式为文本非json格式,修改配置文件即可输出json格式便于收集以及绘图 修改nginx配置文件添加配置,增加一个json输出格式的日志格式 log_format a ...

  8. uploadify3.2.1 多文件上传总是只能上传一个文件

    再网上找了老半天原因,有人说是上传时调用方法参数应该加上*号(:$('#mulfile_upload').uploadify('upload','*');) 总是不行, 我怀疑下面的原因: 我就以为是 ...

  9. 《机器学习实战》2.2.2分析数据:使用matplotlib创建散点图

    #输出散点图 def f(): datingDataMat,datingLabels = file2matrix("datingTestSet3.txt") fig = plt.f ...

  10. MySQL复制日常维护与管理

    一.复制一些常见设置 1.mysql复制启动时参数: mysql启动时的参数包括:master_host,master_port,master_user,master_password,master_ ...