问题描述:给出10w条人和人之间的朋友关系,求出这些朋友关系中有多少个朋友圈
样例A-B、B-C、D-E、E-F ,这四对关系中存在2个朋友圈
解题思路:并查集,而题目只需要求出朋友圈数量,并不需要求出各朋友圈,所以该并查集的实现也可以非常简单。
A-B,就把father[B] = A,处理每条朋友关系即可得到结果。
而关于并查集的介绍,已有很多博文有所阐述,这里就不啰嗦了。
如下给出实现的并查集
Python实现
class WeightedUF(): fatherid=[] sz=[] count=0 def __init__(self,n): self.count=n self.fatherid=[i for i in range(n)] self.sz=[0 for i in range(n)] def getcount(self): return self.count def connected(self,p,q): return self.find(p)==self.find(q) def find(self,p): while p !=self.fatherid[p]: p=self.fatherid[p] return p def pathcompressionfind(self,p): if p==self.fatherid[p]: return p else: self.fatherid[p]=self.pathcompressionfind(self.fatherid[p]) return self.fatherid[p] def union(self,p,q): i=self.find(p) j=self.find(q) if i==j: return if self.sz[i]<self.sz[j]: self.fatherid[i]=j self.sz[j]+=self.sz[i] else: self.fatherid[j]=i self.sz[i]+=self.sz[j] self.count-=1
Java实现
public class WeightUF { int[] fatherid ; int[] sz; int count = 0; public WeightUF(int n){ this.count = n; this.fatherid = new int[n]; this.sz = new int[n]; for(int i=0;i<n;i++){ fatherid[i] = i; sz[i] = 0; } } public int getCount(){ return count; } public boolean connected(int p,int q){ return find(p) == find(q); } public int find(int p){ while (p != fatherid[p]){ p = fatherid[p]; } return p; } public int pathcompressionfind(int p){ if(p == fatherid[p]){ return p; } else{ fatherid[p] = pathcompressionfind(p); return fatherid[p]; } } public void union(int p,int q){ int i = find(p); int j = find(q); if(i == j){ return; } if(sz[i] < sz[j]){ fatherid[i] = j; sz[j] += sz[i]; } else{ fatherid[j] = i; sz[i] += sz[j]; } count -= 1; } }
测试样例(java)
public static void main(String[] args) { WeightUF weightUF = new WeightUF(10); weightUF.union(9,2); weightUF.union(9,3); weightUF.union(1,2); weightUF.union(5,4); System.out.println(weightUF.getCount()); System.out.println(weightUF.connected(9,4)); System.out.println(weightUF.connected(9,5)); }