Time Limit: 10000MS | Memory Limit: 65536K | |
Total Submissions: 33086 | Accepted: 10840 |
Description
Input
Output
Sample Input
2 3 3 1 2 2 3 1 3 4 2 1 2 3 4
Sample Output
Scenario #1: Suspicious bugs found! Scenario #2: No suspicious bugs found!
Hint
Source
题意:有n个人,每个人都有一个编号,现在有m组输入(x,y),表示x喜欢y(y喜欢x),问通过这些关系能否找出同性恋?
题解:很容易想到使用并查集,但是并不是很好写呀Orz,我开始是考虑使用2个根来表示关系,突然有发现这些数字关系有可能会形成森林,这时我们需要使用数组,记录每个根的对立面的集合,每次添加到他们对立的集合,即男女集合,这样就不用考虑它是否会形成森林,直接合并即可,这里注意在一些元素根本不知道属性的情况下是不去要合并它的对立面的
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<map> #include<set> #include<queue> #include<string> #include<bitset> #include<utility> #include<functional> #include<iomanip> #include<sstream> #include<ctime> using namespace std; #define N int(1e6+10) #define inf int(0x3f3f3f3f) #define mod int(1e9+7) typedef long long LL; pair<int,int>pat[N]; int fa[N],Rank[N]; void init(int n) { for(int i=1;i<=n;i++) { pat[i].first=0; Rank[i]=1; fa[i]=i; } } int find(int x) { return fa[x]==x?x:fa[x]=find(fa[x]); } void unio(int x,int y) { x=find(x); y=find(y); if(x!=y) { if(Rank[x]>Rank[y]) { Rank[x]+=Rank[y]; fa[y]=fa[x]; } else { Rank[y]+=Rank[x]; fa[x]=fa[y]; } } } int main() { #ifdef CDZSC freopen("i.txt", "r", stdin); //freopen("o.txt","w",stdout); int _time_jc = clock(); #endif int t,n,m,cas=0,x,y; scanf("%d",&t); while(t--) { int ok=1; printf("Scenario #%d:\n",++cas); scanf("%d%d",&n,&m); init(n); while(m--) { scanf("%d%d",&x,&y); if(pat[x].first==0&&pat[y].first==0) { pat[x].first=y; pat[y].first=x; continue; } else { int xx=find(x); int yy=find(y); if(xx==yy) { ok=0; } else { if(pat[xx].first!=0) { unio(y,pat[xx].first); } else { pat[xx].first=xx; } if(pat[yy].first!=0) unio(x,pat[yy].first); else { pat[yy].first=yy; } } } } puts(ok?"No suspicious bugs found!\n":"Suspicious bugs found!\n"); } return 0; }