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. dyld: DYLD_ environment variables being ignored because main executable (/usr/bin/sudo) is setuid or setgid

    这两个变量被设置了 DYLD_LIBRARY_PATH *或* LD_LIBRARY_PATH, 用下面的明令查找一下,一般在.bash_profile, .bashrc 等文件中.执行brew do ...

  2. nagios监控报错 It appears as though you do not have permission to view...

    今天在安装完nagios后,通过nagios网页界面点击主机.服务.问题页面时.均报错,报错的内容都差不多.如点击服务,报错: It appears as though you do not have ...

  3. 【BZOJ3413】匹配 离线+后缀树+树状数组

    [BZOJ3413]匹配 Description Input 第一行包含一个整数n(≤100000). 第二行是长度为n的由0到9组成的字符串. 第三行是一个整数m. 接下来m≤5·10行,第i行是一 ...

  4. [分布式系统学习]阅读笔记 Distributed systems for fun and profit 之四 Replication 拷贝

    阅读http://book.mixu.net/distsys/replication.html的笔记,是本系列的第四章 拷贝其实是一组通信问题,为一些子问题,例如选举,失灵检测,一致性和原子广播提供了 ...

  5. ThinkPHP widge使用示例

    1.widge一般用于公用模块的设计与使用,以便加强软件模块的复用性与重用性 一般使用include方法设计公共模块,比如<include file="home:header" ...

  6. PAT甲1101 Quick Sort

    1101 Quick Sort (25 分) There is a classical process named partition in the famous quick sort algorit ...

  7. hdu 1525 Euclid's Game【 博弈论】

    Two players, Stan and Ollie, play, starting with two natural numbers. Stan, the first player, subtra ...

  8. CodeForces - 768C Jon Snow and his Favourite Number 桶排

    https://vjudge.net/problem/CodeForces-768C 题意:n个数,k次操作,x.每次操作先排序,再让奇数位置上的数据a[i]:=a[i] XOR x;   k< ...

  9. Oracle备份恢复之断电导致控制文件和日志文件损坏修复

    Oracle数据库遭遇断电遭遇ora-00214.ora-00314.ora-00312错误恢复案例一枚 1.数据库在17日21:19启动开始报错ora-214错误: Tue Jan 17 21:19 ...

  10. Python实现简单HTTP服务器(一)

    一.返回固定内容 # coding:utf-8 import socket from multiprocessing import Process def handle_client(client_s ...