http://poj.org/problem?id=1182

关于并查集 很好的一道题,开始也看了一直没懂。这次是因为《挑战程序设计竞赛》书上有讲解看了几遍终于懂了。是一种很好的思路,跟网上其他的不太一样。

因为N和K很大,所以必须高效维护动物之间的关系,并快速判断是否产生了矛盾,并查集是维护 "属于同一组"的数据结构,,但是在本题中,并不是只有属于同一类的信息,

还有捕食关系的存在,因此需要开动脑筋维护这些关系。

对于每只动物 i 创建3个元素 i-A,i-B,i-C,并用着3×N个元素建立并查集。这个并查集维护如下信息:

i-x 表示 ”i属于种类 x“;

并查集里的每一组表示组内所有元素代表的情况都同时发生或不发生。

例如,如果i-A和j-B 在同一个组里,就表示如果i属于种类A那么j一定是属于种类B,如果j属于种类B,那么i一定属于种类A,因此,对于每一条信息,只需要按照下面进行操作就可以

第一种:x和y属于同一种类,合并x-A和y-A,x-B和y-B,x-C和y-C.

第二种:x吃y                    合并x-A和y-B,x-B和y-C,x-C和y-A.

不过在合并之前,需要判断合并是否会产生矛盾,例如在第一种信息的情况下,需要检查比如x-A和y-B或者y-C是否在同一组的等信息。

 #include <cstdio>
const int maxn = ; int par[maxn]; //父亲
int rank[maxn]; //树的高度 int N,K;
int T[maxn],X[maxn],Y[maxn]; //T是类型
//初始化n个元素
void init(int n) {
for(int i=; i<n;i++) {
par[i]=i;
rank[i]=;
}
}
//查询树的根
int find(int x) {
if(par[x]==x) {
return x;
}
else return par[x]=find(par[x]);
}
//合并x和y所属集合
void unite(int x,int y) {
x=find(x);
y=find(y);
if(x==y) return; if(rank[x] < rank[y]) {
par[x]=y;
} else {
par[y]=x;
if(rank[x]==rank[y]) rank[x]++;
}
}
//判断x 和y是否属于同一个 集合
bool same(int x,int y) {
return find(x) == find(y);
} void solve() {
//初始化并查集
//元素 x,x+N,x+2*N分别代表x-A,x-B,x-C
init(N*); int ans=;
for(int i=;i<K;i++) {
int t=T[i];
int x=X[i]-,y=Y[i]-;
if(x<||N<=x||y<||N<=y) { //不正确的编号
ans++;
// printf("%d %d\n",x,y);
continue;
} if(t==) {
//x和y属于同一类 并且每次都是3个集合一起合并,所以只需要判断一种情况即可。
if(same(x,y+N)||same(x,y+*N)) { //竟然x和y是同一种类,那么x和y+N,x和y+2N必定不能是同一种
ans++;
}
else { //合并 两个种类,注意我们不清楚 x和y具体是哪个种类,所以必须全部合并
unite(x,y);
unite(x+N,y+N);
unite(x+N*,y+N*);
}
}
else {
//x吃y
if(same(x,y)||same(x,y+*N)) { //x和y在同一组,或者是A,C的情况
ans++;
}
else { //A吃B,B吃C,C吃A
unite(x,y+N);
unite(x+N,y+*N);
unite(x+*N,y);
}
}
}
printf("%d\n",ans);
} int main() {
//freopen("a.txt","r",stdin);
scanf("%d%d",&N,&K);
for(int i=;i<K;i++)
{
scanf("%d%d%d",&T[i],&X[i],&Y[i]);
// printf("%d %d %d\n",T[i],X[i],Y[i]);
}
solve();
return ;
}

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

  1. POJ 1182 食物链 [并查集 带权并查集 开拓思路]

    传送门 P - 食物链 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit  ...

  2. poj 1182 食物链 并查集 题解《挑战程序设计竞赛》

    地址 http://poj.org/problem?id=1182 题解 可以考虑使用并查集解决 但是并不是简单的记录是否同一组的这般使用 每个动物都有三个并查集 自己 天敌 捕食 并查集 那么在获得 ...

  3. POJ 1182 食物链(并查集的使用)

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

  4. poj 1182 食物链 并查集的又一个用法

    食物链   Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 41584   Accepted: 12090 Descripti ...

  5. POJ 1182食物链(并查集)

    食物链Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 85474 Accepted: 25549Description动物王国中有三 ...

  6. POJ - 1182 食物链 并查集经典

    思路:设r(x)表示节点x与根结点的关系,px表示x的根结点.记录每个节点与其父节点的关系,就能很方便知道每个节点以及和它的父节点的关系. struct node{ int par; //父亲节点 i ...

  7. poj——1182食物链 并查集(提升版)

    因为是中文题,题意就不说了,直接说思路: 我们不知道给的说法中的动物属于A B C哪一类,所以我们可以用不同区间的数字表示这几类动物,这并不影响结果,我们可以用并查集把属于一类的动物放在一块,举个例子 ...

  8. POJ 1182 食物链 (并查集)

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

  9. POJ 1182 食物链(并查集)

    题目链接 经过宝哥的讲解,终于对这种问题有了进一步的理解.根据flag[x]和flag[y]求flag[tx]是最关键的了. 0吃1,1吃2,2吃0. 假设flag[tx] = X; 那么X + fl ...

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

    题目传送门:http://poj.org/problem?id=1182 这是一道关系型并查集的题,对于每个动物来说,只有三种情况:同类,吃与被吃: 所以可以用0,1,2三个数字代表三种情况,在使用并 ...

随机推荐

  1. Linux嵌入式系统与硬件平台的关系

    一. Linux嵌入式系统 操作系统是一种在计算机上运行的软件,它的主要任务是管理计算机上的系统资源,为用户提供使用计算机及其外部设备的接口.它存在的目的是为了管理所有硬件资源,并且提供应用软件一个合 ...

  2. phonegap/cordova常用命令

    创建项目 cordova create foldername com.wps.test projectName cd foldername 基本设备信息 设备 API: cordova plugin ...

  3. 一道题DP

    Problem Description 小明明又被大威鱼抓住了,大威鱼把小明明关在地牢里,地牢由n * n 个房间组成,小明被困在地牢的最左上角的房间中,出口在最右下角,他想逃出这个诡异的地牢,但是他 ...

  4. JS读取client端的文件的代码片段

    JS读取client端的文件内容的代码片段 if(window.FileReader){ var html5file = this.pipeDetailFileUpLoader._files[0]; ...

  5. HDOJ 1028 Ignatius and the Princess III (母函数)

    Ignatius and the Princess III Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K ...

  6. C++堆栈与函数调用

    一.C++程序内存分配 1)在栈上创建.在执行函数时,函数内局部变量的存储单元都在栈上创建,函数结束是,这些存储单元自动被释放.栈内存的分配运算内置于处理器的指令集中,一般采用寄存器来存取,效率很高但 ...

  7. POJ 3301 Texas Trip (三分)

    题目链接 题意 : 给你若干个点,让你找最小的正方形覆盖这所有的点.输出面积. 思路 : 三分枚举正方形两对边的距离,然后求出最大,本题用的是旋转正方形,也可以用旋转点,即点的相对位置不变. 正方形从 ...

  8. CF 197 DIV2 Xenia and Bit Operations 线段树

    线段树!!1A 代码如下: #include<iostream> #include<cstdio> #define lson i<<1 #define rson i ...

  9. 关于null == 0?返回false的问题

    1.首先我们先看各种情况的结果: null > 0? //=>false null < 0? //=>false null >= 0? //=>true null ...

  10. android真机自动化测试

    appium执行用例时报错问题: 问题解析: 一般该种情况都是因为来连接了多个设备,验证办法:cmd->执行adb devices  看结果是否是多个devices ,如果是这个问题,停掉多余设 ...