种类并查集
作者:互联网
传送门
食物链
题意:
有三种动物,其食物链形成一个环,即A吃B,B吃C,C吃D。
现在有n个动物,每个动物都属于ABC中的一种,给你k个描述,判断这k种描述的真假,求出假话的总数。
每次描述输入三个数字d,x, y。
d = 1时,表示X和Y是同类
d = 2时,表示X吃Y
思路:
对于每个动物,都有三种可能,可能是A,可能是B,可能是C
所以我们开三倍的数组,将一个数组分成三份来判断——1 到 n是假设一,n + 1 到n * 2是假设二,n * 2 + 1 到 n * 3是假设三
1A 2A 3A
1B 2B 3B
1C 2C 3C
假设1是A
当d=1时,说明2和1是同类,则2就是A。
我们只需要判断1A和2A是不是同类即可
当d=2时,说明1吃2,根据题意,A吃B,所以2是B。
我们只需要判断1A和2B是不是同类即可
假设1是B
当d=1时,说明2和1是同类,则2就是B
我们就判断1B和2B是不是同类即可
当d=2时,说明1吃2,根据题意,B吃C,所以2是C
我们只需要判断1B和2C是不是同类即可
假设1是C
当d=1时,说明2和1是同类,则2就是C
我们只需要判断1C和2C是不是同类即可
当d=2时,说明1吃2,根据题意,C吃A,所以2是A
我们只需要判断1C和2A是不是同类即可
所以对于d = 1,说明1和2必须是同类,也就是find(1) = find(2),抽象化一下就是find(x) == find(y) find(x + n) == find(y + n) find(x + n * 2) == find(y + n * 2),我们只需要找到不等的情况,让sum++即可,对于相等的情况来说,就是正确的,我们就把三种情况分别进行合并
对于d = 2,说明1吃2,根据题中的对应关系,抽象化成find(x) = find(y + n),find(x + n) = find(y + n * 2), find(x + n * 2) = find(y),操作同上
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <stdlib.h>
#include <sstream>
#include <map>
#include <set>
using namespace std;
#define inf 0x3f3f3f3f
#define MAX 150000 + 5
typedef long long ll ;
inline int IntRead(){
char ch = getchar();int s = 0, w = 1;
while(ch < '0' || ch > '9'){
if(ch == '-') w = -1;
ch = getchar();}
while(ch >= '0' && ch <= '9'){
s = s * 10 + ch - '0';ch = getchar();}
return s * w;
}
int n, fa[MAX];
//初始化一定要记得是对n * 3 的数进行初始化
void init(){
for(int i = 1; i <= n * 3; ++i) fa[i] = i;
}
int find(int x){//找根
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
void emerge(int x, int y)
{
fa[find(x)] = find(y);
}
int main()
{
int d, k ,x, y, sum = 0;
cin>>n>>k;
init();
for(int i = 1; i <= k; ++i){
cin>>d>>x>>y;
if(x > n || y > n){
sum++;
continue;
}
//x 代表x是a,x + n代表x是b, x + 2 * n代表x是c
if(d == 1){
if(find(x) == find(y + n) || find(x) == find(y + n * 2)){
sum++;
continue;
}
emerge(x, y);//合并
emerge(x + n, y + n);
emerge(x + n * 2, y + n * 2);
}
else if(d == 2){
if(find(x) == find(y) || find(x) == find(y + n * 2)){
sum++;
continue;
}
emerge(x, y + n);
emerge(x + n, y + n * 2);
emerge(x + n * 2, y);
}
}
cout<<sum<<endl;
return 0;
}
标签:emerge,ch,题意,查集,同类,include,find,种类 来源: https://www.cnblogs.com/chelsea0901/p/14438116.html