poj2492 a bug's life(并查集)
第一眼见这题目还以为它说的是一个bug的一生。。
带权dsu。
比普通并查集多记录了额外的信息,比如这道相对于父亲节点的关系。
我们并不care它爸爸到底是男是女,或者它自己是男是女,我们只需要知道它们是不是同类。
用1表示异性,0表示同性,这是一个找同性恋的题。
公式可以用%的形式写,也可以像我这样写个if然后讨论一下。
对并查集有了更深的理解,它能够整合有关联的节点。
对输入的a,b,如果它们的爸爸不是同一个人,说明在这之前它们都是互相独立的,一直到现在才产生了联系。
比较坑的是输出的格式,大小写什么的,两个\n什么的,在这边送了好几发。
#include <iostream> #include <math.h> #include <string.h> #include <vector> #include <map> #include <queue> #include <stdio.h> #include <algorithm> #include <cstdio> using namespace std; int n,m,fa[100001],relation[100001]; int find(int x) { if(fa[x]!=x) { int tmp=fa[x]; fa[x]=find(fa[x]); if(relation[x]==1) { relation[x]=relation[tmp]; } //同 else { relation[x]=-relation[tmp]; } } return fa[x]; } void pre( ) { for(int i=1;i<=n;i++) { relation[i]=1; fa[i]=i; //自己跟自己 难道是异性 } } int main( ){ /* 2 3 3 1 2 2 3 1 3 4 2 1 2 3 4 */ //freopen("927.in","r",stdin); int t; cin>>t; for(int k=1;k<=t;k++) { int ok=1; cin>>n>>m; pre( ); for(int j=1;j<=m;j++) { int a,b; cin>>a>>b; int f1=find(a),f2=find(b); if(f1==f2) { if(relation[a]==relation[b]) { ok=0; } } else { if(relation[b]==1) { fa[f2]=f1; relation[f2]=-relation[a]; // cout<<a<<" "<<b<<" "<<f1<<" "<<f2<<" "<<relation[f2]<<" "<<fa[f2]<<endl; } else { fa[f2]=f1; relation[f2]=relation[a]; } } // cout<<a<<" "<<b<<" "<<f1<<" "<<f2<<" "<<relation[f2]<<endl; } if(ok==0) { printf("Scenario #%d:\nSuspicious bugs found!\n\n", k); } else { printf("Scenario #%d:\nNo suspicious bugs found!\n\n", k); } } }