并查集之判断是否是二分图
(定义:设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。)
题意呵呵呵,男女各站一边,找出那对同性恋!
这里对每一对关系a和b,把自己的另一半和之前的另一半(如果有的话)合并,即他们是一个性别的。给出一对要判断的关系,如果两个点同时属于一边,则不是二分图,题目里面就是同性了。
#include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #define inf 0x3f3f3f3f #define ll __int64 using namespace std; int r[2005],n,m,ans,pos[2005]; int root(int a) { if(r[a]==a) return a; else return r[a]=root(r[a]); } void merge(int a,int b) { int ra,rb; ra=root(a); rb=root(b); if(ra==rb) return;//不能在这把ans=0,这里的a和b是要合并的同性,而不是要判断的异性啊 else if(ra<rb) r[rb]=ra; else r[ra]=rb; } int main() { int cnt=0,a,b,t,i; scanf("%d",&t); while(t--) { cnt++; scanf("%d%d",&n,&m); ans=1; memset(pos,0,sizeof pos); for(i=0;i<=n;i++) r[i]=i; while(m--) { scanf("%d%d",&a,&b); if(root(a)==root(b)) ans=0; if(ans) { if(!pos[a]&&!pos[b]) { pos[a]=b; pos[b]=a; } else if(!pos[a]) { pos[a]=b; merge(a,pos[b]); } else if(!pos[b]) { pos[b]=a; merge(b,pos[a]); } else { merge(a,pos[b]); merge(b,pos[a]); } } } printf("Scenario #%d:\n",cnt); if(ans) printf("No suspicious bugs found!\n\n"); else printf("Suspicious bugs found!\n\n"); } return 0; }
hdu 1829 A Bug's Life,布布扣,bubuko.com
原文:http://blog.csdn.net/u011032846/article/details/20565145