题目大意:输入一个数t,表示测试组数。然后每组第一行两个数字n,m,n表示有n只昆虫,编号从1—n,m表示下面要输入m行交配情况,每行两个整数,表示这两个编号的昆虫为异性,要交配。要求统计交配过程中是否出现冲突,即是否有两个同性的昆虫发生交配。
思路:并查集,和1703几乎一样的思路。
#include <iostream> using namespace std; #include <memory.h> #include <stdio.h> // Model 1 const int MAXSIZE = 2010; int rank[MAXSIZE];//rank[x]表示x的秩 int parent[MAXSIZE]; int n;//集合元素,从1到n int m; int opposite[MAXSIZE]; /* 查找x元素所在的集合,回溯时压缩路径*/ int FindSet(int x) { if (x!=parent[x]) parent[x]=FindSet(parent[x]); return parent[x]; } //Union按秩合并,即合并的时候将元素少的集合合并到元素多的集合中,这样合并之后树的高度会相对较小 //通过秩rank的大小来衡量元素的多少 void Union(int root1, int root2) { int x=FindSet(root1),y=FindSet(root2); if (x==y) return; if (rank[x]>rank[y]) parent[y]=x; else { parent[x]=y; if (rank[x]==rank[y]) ++rank[y]; } } void Initialization() { int i; memset(rank,0,sizeof(rank)); memset(opposite,0,sizeof(opposite)); for (i=1;i<=n;i++) parent[i]=i; } int main() { int case_num,case_ctr,i,j; int flag; int x,y; scanf("%d",&case_num); for (case_ctr=1;case_ctr<=case_num;case_ctr++) { flag=1; scanf("%d%d",&n,&m); Initialization(); for (i=0;i<m;i++) { scanf("%d%d",&x,&y); if (flag==1) { if (FindSet(x)==FindSet(y)) flag=0; if (opposite[x]==0&&opposite[y]==0) { opposite[x]=y; opposite[y]=x; } else if (opposite[x]==0) { opposite[x]=y; Union(x,opposite[y]); } else if (opposite[y]==0) { opposite[y]=x; Union(y,opposite[x]); } else { Union(x,opposite[y]); Union(y,opposite[x]); } } } printf("Scenario #%d:\n",case_ctr); if (flag==1) printf("No suspicious bugs found!\n"); else printf("Suspicious bugs found!\n"); printf("\n"); } return 0; }