假设有N个用户,其中有些人是朋友,有些则不是。A和B是朋友,B和C是朋友,这样ABC就是一个朋友圈,请计算给定的朋友关系的朋友圈数。  
     给定一个 N * N 的矩阵 M,表示用户之间的朋友关系。如果M[i][j] = 1,表示已知第 i 个和 j 个人互为朋友关系,否则为不知道。你必须输出所有用户中的已知的朋友圈总数。
  
 第一行输入为表示用户数N第2到1+N行表示朋友之间关系,如果值为1表示有朋友关系
输出朋友圈数
3 1,1,0 1,1,0 0,0,1
2
第0个用户和第1个用户组成一个朋友圈,第2个用户组成一个朋友圈
3 1,1,0 1,1,1 0,1,1
1
第0,1,2个用户组成了一个朋友圈
如果M[i][j] = 1 那么 如果M[j][i] = 1,用户自己和自己肯定是朋友关系即M[i][i]=1用户数量不超过10000
import java.io.*;
import java.util.*;
public class Main{
    
    
    public static void main(String[] args)throws Exception{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        int[][] arr = new int[n][n];
        for(int i=0;i<n;++i){
            String[] arg = br.readLine().split(",");
            for(int j=0;j<n;++j){
                arr[i][j] = Integer.parseInt(arg[j]);
            }
        }
        
        int[] f = new int[n];
        for(int i=0;i<n;++i){
            f[i]=i;
        }
        
        for(int i=0;i<n;++i){
            for(int j=0;j<n;++j){
                if(arr[i][j] == 1){
                    union(f,i,j);
                }
            }
        }
        int ans =0;
        for(int i=0;i<n;++i){
            if(f[i]==i){
                ans++;
            }
        }
        System.out.println(ans);
    }
    
    public static int find(int[] f, int a){
        if(f[a]==a){
            return a;
        }
        return f[a] = find(f,f[a]);
    }
    public static void union(int[] f, int a,int b){
        int fa = find(f,a);
        int fb = find(f,b);
        f[fa]=fb;
    }
} 从每个未访问过的节点(用户)出发,进行 dfs 搜索。
dfs 的次数,就是朋友圈的数目。
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Main {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int n = scanner.nextInt();
    String[][] relations = new String[n][n];
    for (int i = 0; i < n; i++) {
      relations[i] = scanner.next().split(",");
    }
    scanner.close();
    System.out.println(friendCircle(relations));
  }
  private static int friendCircle(String[][] relations) {
    int n = relations.length;
    // graph[i] -> 用户 i 的所有朋友
    Set[] graph = new HashSet[n];
    for (int i = 0; i < n; i++) {
      graph[i] = new HashSet();
      for (int j = 0; j < n; j++) {
        int relation = Integer.parseInt(relations[i][j]);
        if (relation == 1) {
          graph[i].add(j);
        }
      }
    }
    int ans = 0;
    boolean[] visited = new boolean[n];
    for (int i = 0; i < n; i++) {
      if (!visited[i]) {
        ans++;
        dfs(graph, i, visited);
      }
    }
    return ans;
  }
  private static void dfs(Set[] graph, int cur, boolean[] visited) {
    visited[cur] = true;
    for (int next : graph[cur]) {
      if (!visited[next]) {
        dfs(graph, next, visited);
      }
    }
  }
}
                                                                                    用一个set集合存储朋友圈列表。通过&与操作判断是否存在朋友关系,通过|或操作进行朋友圈融合,set集合剩下多少个元素代表有多少个朋友圈
public static void main(String[] args) { Scanner in = new Scanner(System.in); // 注意 hasNext 和 hasNextLine 的区别 int arrLen = Integer.parseInt(in.nextLine()); Set<Integer> binaryIntFC = new HashSet<>(); for (int i = 0; i < arrLen; i++) { String line = in.nextLine(); String[] split = line.split(","); StringBuilder sb = new StringBuilder(); for (int j = 0; j < split.length; j++) { sb.append(Integer.parseInt(split[j])); } binaryIntFC.add(Integer.parseInt(sb.toString(), 2)); } Set<Integer> friendCircles = new HashSet<>(); for (Integer binaryInt : binaryIntFC) { if (friendCircles.size() == 0) { friendCircles.add(binaryInt); continue; } // 判断当前set值与目标setlist是否有朋友关系,决定是否进行融合 boolean isFriend = false; for (Integer targetIntSet : friendCircles) { if ((targetIntSet & binaryInt) > 0) { // 有朋友关系,进行融合 int mergeInt = targetIntSet | binaryInt; friendCircles.remove(targetIntSet); friendCircles.add(mergeInt); isFriend = true; break; } } if (!isFriend) { // 没有朋友关系,直接加入到目标setlist中,成为一个新的朋友圈 friendCircles.add(binaryInt); } } System.out.println(friendCircles.size()); }
import java.util.*;
public class Main {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            String s = sc.nextLine();
            int n = Integer.parseInt(s);
            UnionFindSet ufs = new UnionFindSet(n);
            int res = n;
            for (int i = 0; i < n; i++) {
                s = sc.nextLine();
                String[] ss = s.split(",");
                for (int j = 0; j < i; j++) {
                    int cur = Integer.parseInt(ss[j]);
                    if (cur == 1) {
                        res = ufs.union(i, j);
                    }
                }
            }
            sc.close();
            System.out.println(res);
        }
        static class UnionFindSet {
            int[] parent;
            int size;
            UnionFindSet(int n) {
                this.parent = new int[n];
                for (int i = 0; i < n; i++) {
                    parent[i] = i;
                }
                this.size = n;
            }
            int find(int n) {
                if (n == parent[n]) {
                    return n;
                }
                int r = find(parent[n]);
                parent[n] = r;
                return r;
            }
            int union(int n1, int n2) {
                int r1 = find(n1), r2 = find(n2);
                if (r1 == r2) {
                    return size;
                } else {
                    if (r1 < r2) {
                        parent[r2] = r1;
                    } else {
                        parent[r1] = r2;
                    }
                    return --size;
                }
            }
        }
    }
 #include <iostream>
#include <vector>
using namespace std;
// 并查集
class UnionFind
{
public:
    UnionFind(size_t n)
        :_v(n, -1)
    {}
    
    int FindIdx(int index)
    {
        while(_v[index] >= 0)
        {
            index = _v[index];
        }
        return index;
    }
    
    bool Merge(int idx1, int idx2)
    {
        int root1 = FindIdx(idx1);
        int root2 = FindIdx(idx2);
        if(root1 == root2)
            return false;
        _v[root1] += _v[root2];
        _v[root2] = root1;
        return true;
    }
    
    size_t Count() const
    {
        size_t count = 0;
        for(const auto& e : _v)
        {
            if(e < 0)
                count++;
        }
        return count;
    }
    
    vector<int> _v;
};
int main()
{
    int n;
    while(cin >> n)
    {
        vector<vector<int>> v(n, vector<int>(n, 0));
        UnionFind uni(n);
        for(int i = 0; i < n; i++)
        {
            string str;
            cin >> str;
            for(int j = 0, k = 0; j < n; j++, k += 2)
                v[i][j] = str[k] - '0';
        }
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(i == j)
                    continue;
                if (v[i][j] == 1)
                    uni.Merge(i, j);
            }
        }
        
        cout << uni.Count() << endl;
        
    }
    return 0;
}
 #include <iostream>
bool temp[10001][10001];
int pre[10001]; //前驱
int unionsearch(int root) {
    int son, tmp;
    son = root;
    while (root != pre[root]) root = pre[root]; //寻找最终节点
    while (son != root) { //路径压缩(递归)
        tmp = pre[son];
        pre[son] = root; //root是最终节点 
        son = tmp; //向前寻找 
    }
    return root;
}
int main() {
    int a, b;
    int root1, root2;
    int total;
    char c;
    std::cin>>a;
    total = a;
    for(int i = 0; i < a; i++){
        pre[i] = i;
        for(int j = 0; j < a; j++){
            std::cin>>b;
            if(b == 1) temp[i][j] = true;
            if(j != a-1) std::cin>>c;
        }
    }
    for(int i = 0; i < a; i++){
        for(int j = 0; j < i / 2 + 1; j++){
            if(temp[i][j] == temp[j][i] && j!=i && temp[i][j]){
                root1 = unionsearch(i);
                root2 = unionsearch(j);
                if(root1 != root2){
                    pre[root1] = root2;
                    total--;
                }
            }
        }
    }
    std::cout<<total;
    return 0;
} import java.util.Scanner;
/**
 * @author Frank KONG
 * @version 1.0
 * @date 2021/2/24 10:47
 */
public class Main {
    public static void main(String[] args) {
        int n;
        Scanner scanner = new Scanner(System.in);
        n = scanner.nextInt();
        int[][] graph = new int[n][n];
        for(int i = 0; i < n; i++){
            String s = scanner.next();
            String[] split = s.split(",");
            for(int j = 0; j < n; j++){
                graph[i][j] = Integer.valueOf(split[j]);
            }
        }
        //0~n-1编号
        int[] parent = new int[n];
        for(int i = 0; i < n; i++){
            parent[i] = i;
        }
        for(int i = 0; i < n; i++){
            for(int j = 0; j < n; j++){
                if(graph[i][j] == 1){
                    //有关系,加入集合
                    int parentI = find(parent, i);
                    int parentJ = find(parent, j);
                    if(parentI != parentJ){
                        parent[parentI] = parentJ;
                    }
                }
            }
        }
        //查看有几个集合
        int res = 0;
        for(int i = 0; i < n; i++){
            if(parent[i] == i) res++;
        }
        System.out.println(res);
    }
    public static int find(int[] parent, int index){
        if(parent[index] != index){
            index = parent[index];
        }
        return index;
    }
}