poj1182

原创 2016年08月31日 10:13:24
/*
translation:中文题
solution:
	并查集
	本题除了需要维护相同集合的这个关系外还需要维护不同集合间的关系,如果像图论那样开个数组来
	维护集合之间的关系会MLE。所以需要在并查集上进行改造使其能够表示不同集合之间的关系。方法
	如下:因为总共只有三个大的集合,只是不知道每个元素属于这三个集合中的哪一个,所以并查集中
	的元素形式可以改变成i~a,表示i号元素属于a集合。每次合并时并不知道这个元素属于哪个集合,
	所以干脆将i~a,i~b,i~c都并在一起!所以这个时候并查集内每个组的意义就是:表示组内的元素
	同时发生或者同时不发生!

note:
	1:主要是如何维护不同集合之间的关系想不出来,今后再次遇到这种需要频繁查询关系,且还需要维
	护不同集合之间的关系的题目,可以参考本题的方法。
	2:因为元素有n个,所以用i, i+n, i+2*n来表示i~a,i~b,i~c。

date:
	2016.8.31
*/
#include <iostream>
#include <cstdio>

using namespace std;
const int maxn = 50000 + 1;

int par[maxn * 3], height[maxn * 3];	//父节点以及高度
int n, k;

void init(int s) {
	for(int i = 1; i <= s; i++) {
		par[i] = i;
		height[i] = 0;
	}
}

int get_root(int x) {
	if(par[x] == x) {
		return x;
	}
	else {
		return par[x] = get_root(par[x]);
	}
}

void unite(int x, int y) {
	x = get_root(x);
	y = get_root(y);
	if(x == y)	return;

	if(height[x] < height[y]) {
		par[x] = y;
	}
	else {
		par[y] = x;
		if(height[x] == height[y])	height[x]++;
	}
}

inline bool same(int x, int y) {
	return get_root(x) == get_root(y);
}

int main()
{
	//freopen("in.txt", "r", stdin);

    scanf("%d%d", &n, &k);
	init(n * 3);

    int d, x, y, ans = 0;
    for(int i = 1; i <= k; i++) {
		scanf("%d%d%d", &d, &x, &y);
		if(x > n || y > n || x < 1 || y < 1) { ans++; continue; }

		if(d == 1) {	
			if(same(x, y + n) || same(x, y + 2 * n)) { ans++; continue; }
			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++; continue; }
			unite(x, y + n);
			unite(x + n, y + 2 * n);
			unite(x + 2 * n, y);
		}
    }

    printf("%d\n", ans);

    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

POJ-1182 食物链

题目链接:http://poj.org/problem?id=1182 解题思路: 这道题是并查集题目中的经典。。。而且比普通并查集提高了一个档次,下面在基础并查集的前提上讲解并查集的真正用法。 ...

poj 1182 食物链的一种解法(详解),非向量法

食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 54761   Accepted: 16056 D...

poj 1182 食物链(并查集+向量偏移)

这道食物链实在让我纠结了好久。。。1182 食物链(并查集+向量偏移)" title="poj 1182 食物链(并查集+向量偏移)" style="margin-top:0px; margin-ri...

poj 1182 并查集经典问题

http://poj.org/problem?id=1182 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。  现有N个动物...

POJ 1182 食物链 -- 解题报告

食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 70529   Accepted:...
  • fjinhao
  • fjinhao
  • 2017年04月16日 01:18
  • 302

POJ1182 - 食物链(带权并查集)

题目链接:http://poj.org/problem?id=1182题目大意:动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。 现有N个动物,以1-...

poj1182食物链(种类并查集)

题目链接:

【解题报告】 POJ 1182 食物链 并查集的经典应用+相对位置

题目连接:POJ 1182 题目主要是得考虑找一个元素当这个集合的祖先,然后将其他两两动物之间的身份转变到对祖先的身份即可,这里用到一个向量转换相对身份,其实定义是可以改变的,一旦改变身份转换公式将...

食物链(POJ - 1182)带权并查集 种类并查集

本题学习到了带权并查集的神奇之处! 在网上看到了各位前辈对此题的精妙的解析,不由得感叹连连。尤其是各位前辈的认真,让我也忍不住想要把这个题用我自己的方式再融会贯通一遍。 (一)各个变量的定义 d:...

POJ1182_带权并查集基础(注释很详尽)

/* 带权并查集是普通并查集的一个拓展。 普通的并查集只是集合,而带权并查集的集合是有关系的集合。集合中的元素有他们之间的相互关系 */#include using namespace std; co...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:poj1182
举报原因:
原因补充:

(最多只允许输入30个字)