首页 > 其他分享 >POJ 1182 食物链

POJ 1182 食物链

时间:2023-05-26 15:02:12浏览次数:50  
标签:食物链 int 1182 节点 merge POJ 3n 2n find


解题思路:并查集经典中的经典题,在网上看了很多大牛的思路,大部分是增加一个结构体存动物间的关系,结合并查集判断,但是关系域的更新比较复杂,一下子不太容易理解。所以就有人另开思路,这里介绍一个十分巧妙的思路。

一般我们都会把一个动物当成一个节点,然后去执行并查集等操作。但是有位大牛另辟蹊径,给每个动物赋予三个节点(n,2n,3n),这样就将并查集的节点数量扩展到3n,用并查集维护这3n个节点的信息就行。下面是具体的思路和操作: 
1 先来考虑什么情况下a和b两个动物是同类: 
(1)a吃c,b也吃c,则a和b同类; 
(2)a吃c,c吃d,d吃b,则a和b同类; 

2 有了上面的基础,我们还需要巧妙的定义下面的规则: 
(1)如果a和b是同类,则a的三个节点(a_n,a_2n,a_3n)分别指向b的对应的三个节点(b_n,b_2n,b_3n),即a_n -> b_n , a_2n -> b_2n , a_3n -> b_3n; 

POJ 1182 食物链_并查集

(2)如果a吃b,则a的三个节点(a_n,a_2n,a_3n)分别指向对应b的三个节点(b_n,b_2n,b_3n)的下一个节点,即a_n -> b_2n , a_2n -> b_3n , a_3n -> b_n;

 

POJ 1182 食物链_并查集_02

 

3 所以我们现在可以表示1中提到的两种同类的情况了: 
(1) 

POJ 1182 食物链_g++_03

(2) 

POJ 1182 食物链_并查集_04

按照上面的规则对每一个动物去建立关系,那么,如果a和b是同类,肯定有a_n与b_n连通,即有相同的根节点;如果a吃b,肯定有a_n与b_2n连通;如果b吃a,肯定有b_n与a_2n连通。

#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 300010;
int pre[maxn];
void Init()
{
	for(int i = 0;i < maxn; i++)
		pre[i] = i;
} 
int find(int x)
{
	while(x != pre[x])
	{
		x = pre[x];
	}
	return x;
}
void merge(int x,int y)
{
	int a = find(x);
	int b = find(y);
	if(a != b)
		pre[b] = a;
}
int main()
{
	int n,k,d,x,y,flag = 0;
	Init();
	scanf("%d %d",&n,&k);
	for(int i = 0;i < k; i++)
	{
		scanf("%d %d %d",&d,&x,&y);
		if(x > n || y > n || x < 1 || y < 1 || (d == 2 && x == y))
		{
			flag++;
			continue;
		}
		if(d == 1)
		{
			if(find(x) == find(y + n) || find(y) == find(x + n))
			{
				flag++;
				continue;
			}
			else
			{
				merge(x,y);
				merge(x + n,y + n);
				merge(x + 2 * n,y + 2 * n);
				continue;
			}
		}
		if(d == 2)
		{
			if(find(x) == find(y) || find(y) == find(x + n))
			{
				flag++;
				continue;
			}
			else
			{
				merge(x,y + n);
				merge(x + n,y + 2 * n);
				merge(x + 2 * n,y);
			}
		}
	}
	printf("%d\n",flag);
	return 0;
}

标签:食物链,int,1182,节点,merge,POJ,3n,2n,find
From: https://blog.51cto.com/u_16131191/6356127

相关文章

  • POJ 2251 Dungeon Master(三维BFS)
    题目看起来很厉害,实际上看懂了并不难,开一个三维的数组,这里需要注意的是第一维是高度,然后就是简单的BFS了,还有不同就是三维的时候有六个方向可以走,在前后左右的基础上多了一个向上和向下的走法,还有一个问题就是多个输入样例要注意每次都要初始化,我做的时候就因为这个WA了好几次,最后......
  • POJ 2080 Calendar
    题目链接:http://poj.org/problem?id=2080题目不是很难,也没什么说的,直接看代码吧:#include<iostream>#include<stdio.h>usingnamespacestd;intyear(intm){ if(m%4==0&&m%100!=0||m%400==0) return1; else return0;}intmain(){ intn,i,j......
  • 区分PO、VO、 BO、 DTO、 POJO
     分层领域模型规约:DO(DataObject):此结构与数据库表结构一一对应,通过DTO向上传输数据源对象。DTO(DataTransferObject):数据传输对象,Service或Manager向外传输的对象。BO(BusinessObject):业务对象,由Service层输出的封装业务逻辑的对象。AO(ApplicationObject):应用......
  • Tallest Cow(最高的牛)poj3263
    题目描述:FJ'sN(1≤N≤10,000)cowsconvenientlyindexed1..Narestandinginaline.Eachcowhasapositiveintegerheight(whichisabitofsecret).YouaretoldonlytheheightH(1≤H≤1,000,000)ofthetallestcowalongwiththeindexIoftha......
  • poj-1519
    //132K0MSC++#include<cstdio>#include<cstring>usingnamespacestd;longlonggetDigitSum(longlongval){longlongdigitSum=0;if(val<10){returnval;}else{while(val){digitSum+=......
  • poj-2362
    //132K141MSC++withbeginSearchPos#include<cstdio>#include<cstring>#include<cstdlib>usingnamespacestd;intcmp(constvoid*a,constvoid*b)//降序{return*(longlong*)b-*(longlong*)a;}longlongfourEdgeLeng......
  • poj-2371
    //524K63MSC++#include<cstdio>#include<cstring>#include<cstdlib>intcmp(constvoid*a,constvoid*b){return*((int*)a)-*((int*)b);}usingnamespacestd;constintMAX=100001;intarray[MAX];intdataBaseSiz......
  • poj-1930
    //144K0MSC++#include<cstdio>#include<cstring>#include<cmath>intgcd(inta,intb){if(b==0){returna;}elseif(a>b){returngcd(b,a%b);}else{returngcd(a,b%a);}}/......
  • poj-1023
    //184K0MSC++#include<cstdio>#include<cstring>usingnamespacestd;charNP[65];//-1:n,1:pcharstr[80];chardigitUsed[80];charbinaryExpression[80];intcaseNum;intlength;longlongval;voidsolve(longlongval){l......
  • poj-1401
    //408K375MSG++#include<cstdio>#include<cstring>longlongget2FactorNum(longlongN){longlongres=0;while(N){res+=N/2;N/=2;}returnres;}longlongget5FactorNum(longlongN){long......