POJ - 2492 A Bug‘s Life 拓展并查集模板题

题目链接

POJ-2492

题意

给出n个虫子,m个关系,虫子只有两种性别,每条关系告诉你两只虫子是异性,请问是否有矛盾数据?

思路

裸的并查集,带权或者拓展都可以,我这里用的拓展并查集,感觉比带权好写得多

开两倍空间,1-n为虫子自己,n-2n为虫子的性转个体。同一集合内的虫子性别相同。那么对于每个关系u-v,如果发现uv的祖先节点一样,则出现了bug,否则的话,连接u和v+n,u+n和v。

初次写拓展并查集的话可以AC这道题后做一下食物链,我同样写了题解

代码

#include<iostream>
#include<cstdio>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl "\n"
using namespace std;
	typedef long long ll;
	const int maxn=5000;
	const int inf=0x3f3f3f3f;
	int fa[maxn];
	int tn,n,m;
	void init(){
    
    
		for(int i=0;i<maxn;i++)
			fa[i]=i;
	} 
	int find(int x){
    
    
		return x==fa[x]?x:fa[x]=find(fa[x]);
	}
	void unite(int x,int y){
    
    
		int fx=find(x),fy=find(y);
		if(fx==fy)
			return ;
		fa[fx]=fy;
	}
	
	int main(){
    
    
		scanf("%d",&tn);
		for(int _=1;_<=tn;_++){
    
    
			scanf("%d%d",&n,&m);
			init();
			bool bug=0;
			while(m--){
    
    
				int u,v;
				scanf("%d%d",&u,&v);
				if(bug)
					continue;
				int fu=find(u),fv=find(v);
				if(fu==fv)
					bug=1;
				else
					unite(u,v+n),unite(v,u+n);
					
			}
			if(bug)
				printf("Scenario #%d:\nSuspicious bugs found!\n\n",_);
			else
				printf("Scenario #%d:\nNo suspicious bugs found!\n\n",_);
		}
	}

猜你喜欢

转载自blog.csdn.net/TheSunspot/article/details/108046328