class Solution {
public int findCircleNum ( int [ ] [ ] M) {
boolean [ ] visited = new boolean [ M. length] ;
int count = 0 ;
for ( int i = 0 ; i < M. length; i++ ) {
if ( ! visited[ i] ) {
dfs ( M, visited, i) ;
count++ ;
}
}
return count;
}
private void dfs ( int [ ] [ ] M, boolean [ ] visited, int i) {
for ( int j = 0 ; j < M. length; j++ ) {
if ( M[ i] [ j] == 1 && ! visited[ j] ) {
visited[ j] = true ;
dfs ( M, visited, j) ;
}
}
}
}
class Solution {
public int findCircleNum ( int [ ] [ ] M) {
UF uf = new UF ( M. length) ;
for ( int i = 0 ; i < M. length; i++ ) {
for ( int j = 0 ; j < i; j++ ) {
if ( M[ i] [ j] == 1 ) {
uf. union ( i, j) ;
}
}
}
return uf. count ( ) ;
}
class UF {
private int [ ] parents;
private int [ ] ranks;
private int count;
public UF ( int capacity) {
parents = new int [ capacity] ;
ranks = new int [ capacity] ;
count = capacity;
for ( int i = 0 ; i < capacity; i++ ) {
parents[ i] = i;
ranks[ i] = 1 ;
}
}
public void union ( int v1, int v2) {
int p1 = find ( v1) ;
int p2 = find ( v2) ;
if ( p1 == p2) return ;
if ( ranks[ p1] < ranks[ p2] ) {
parents[ p1] = p2;
} else if ( ranks[ p1] > ranks[ p2] ) {
parents[ p2] = p1;
} else {
parents[ p1] = p2;
ranks[ p2] ++ ;
}
count-- ;
}
public int find ( int v) {
while ( parents[ v] != v) {
parents[ v] = parents[ parents[ v] ] ;
v = parents[ v] ;
}
return v;
}
int count ( ) {
return count;
}
}
}