POJ1182食物链之并查集解法
来源:互联网 发布:手机剪裁照片的软件 编辑:程序博客网 时间:2024/06/06 02:10
食物链
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 74500 Accepted: 22124
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
只有一个整数,表示假话的数目。
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
Source
分析:题意就是每次输入一组关系,然后判断这个关系的真假,最后输出假关系的数目.我们可以用数组范围表示,X[2]表示2属于A,X[2+N]表示2属于B,X[2+2N]表示2属于C,3用Y的表示同理.
并查集中的每个组中的元素都有一种关系,本题中这种关系就是:情况的同时发生,如X[2]和Y[3+N]在一个组里,表示2为A的时候3一定为B,这样就表示清楚了2和3的捕食关系.
由于我们不知道2属于哪一类,因此操作的时候3中情况都要考虑到
首先看一下并查集的基本操作int par[150001];int ran[150001];//初始化n个元素void init(int l){ for (int i = 1; i <= l; i += 1){ par[i] = i; ran[i] = 0; }}//判断元素的根int root(int x){ //递归搜索,长处:结构清晰,可记忆化搜索 if (par[x] == x){ return x; }else{ //记忆化搜索,回溯过程中所有节点的父节点直接指向根节点 return par[x] = root(par[x]); } //非递归搜索,长处:效率高,存储空间小 //while (x != par[x]) x = par[x]; //return x;}//判断两个元素是否同组bool same(int x,int y){ return root(x) == root(y);}//合并两个组void unite(int x,int y){ x = root(x); y = root(y); if (x == y) return ; if (ran[x] < ran[y]){ par[x] = y; }else{ par[y] = x; if (ran[x] == ran[y]) ran[x]++; }}
h下面是代码:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;int N,K;int D[150001],X[150001],Y[150001];int par[150001];int ran[150001];void init(int l){ for (int i = 1; i <= l; i += 1){ par[i] = i; ran[i] = 0; }}int root(int x){ if (par[x] == x){ return x; }else{ return par[x] = root(par[x]); }}bool same(int x,int y){ return root(x) == root(y);}void unite(int x,int y){ x = root(x); y = root(y); if (x == y) return ; if (ran[x] < ran[y]){ par[x] = y; }else{ par[y] = x; if (ran[x] == ran[y]) ran[x]++; }}void solve(){ int ans = 0; init(3*N); for (int j = 0; j < K; j += 1){ int d = D[j]; int x = X[j]; int y = Y[j]; if (x < 0 || y < 0 || x > N || y > N){ ans++; } else if (d == 1){ if (same(x,y+N) || same(x,y+2*N)){ ans++; }else{ unite(x,y); unite(x+N,y+N); unite(x+2*N,y+2*N); } } else{ if (same(x,y) || same(x,y+2*N)){ ans++; }else{ unite(x,y+N); unite(x+N,y+2*N); unite(x+2*N,y); } } } printf("%d\n",ans);}int main(){ scanf("%d%d",&N,&K); for (int i = 0; i < K; i += 1) scanf("%d%d%d",&D[i],&X[i],&Y[i]); solve(); return 0;}
- POJ1182食物链之并查集解法
- 食物链 POJ1182 -- 并查集
- poj1182 食物链 (并查集)
- poj1182 并查集 食物链
- poj1182食物链 并查集
- 并查集-POJ1182食物链
- POJ1182 - 食物链 - 并查集
- 并查集 食物链 POJ1182
- poj1182 食物链(并查集)
- POJ1182 食物链 并查集
- Poj1182食物链 (并查集)
- POJ1182 食物链(并查集)
- 【并查集】:poj1182,食物链
- POJ1182 食物链(并查集)
- POJ1182 食物链 并查集
- poj1182 食物链[并查集]
- poj1182 食物链(并查集)
- POJ1182 食物链【并查集】
- C++快速创建Windows服务
- bash 中 $ 与 ! 的使用
- Maze(CodeForces
- Hystrx权威指南--Hystrix调用方法解析
- Jenkins 之 回滚发布操作
- POJ1182食物链之并查集解法
- linux下安装c++ rabbitmq客户端SimpleAmqpClient
- 某次压测时物理内存被用光 Tomcat 被 Kernel kill 掉的案例
- 如何快速高效学习一门新语言
- solr配置dataimport步骤 增量 全量同步配置
- C++学习(56)
- git教程 推荐
- my.cnf互为主从推荐配置
- C++面试中容易问到的知识点