题目思路
看完题目其实就能知道是挺裸的种类并查集
以下是个人对种类并查集的理解:
种类并查集是并查集的一种延申应用
如果并查集表示的关系是亲戚的亲戚是亲戚
那么种类并查集表示的关系就是敌人的敌人是朋友
种类并查集就是将多种类型的人之间的关系用数组存下来
大小一般是普通并查集的多倍
每个长度为n的区间表示一个种类
每次记录关系的时候是对不同区间的点做操作
这题还要注意最后输出要换两次行
ac代码
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 1e6+5;
const int inf = 0x3f3f3f3f;
const ll llinf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1000000007;
//998244353
int f[maxn],flag;
int n,m;
int findx(int x)
{
return f[x]==x?f[x]:f[x]=findx(f[x]);
}
void join(int x,int y)
{
int r1=findx(x);
int r2=findx(y);
if(r1!=r2)
{
f[r1]=r2;
};
}
bool uis(int x,int y)
{
return(findx(x)!=findx(y));
}
int main()
{
int t,ce=0;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=2*n;i++)f[i]=i;
flag=0;
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
if(uis(x,y)&&uis(x+n,y+n))
{
join(x,y+n);
join(x+n,y);
}else
flag=1;
}
printf("Scenario #%d:\n",++ce);
if(flag==1)
{
printf("Suspicious bugs found!\n\n");
}else
{
printf("No suspicious bugs found!\n\n");
}
}
}