原题传送门->省份数量

题目描述

有 n 个城市,其中一些彼此相连,另一些没有相连。如果城市 a 与城市 b 直接相连,且城市 b 与城市 c 直接相连,那么城市 a 与城市 c 间接相连。

省份 是一组直接或间接相连的城市,组内不含其他没有相连的城市。

给你一个 n x n 的矩阵 isConnected ,其中 isConnected[i][j] = 1 表示第 i 个城市和第 j 个城市直接相连,而 isConnected[i][j] = 0 表示二者不直接相连。

返回矩阵中 省份 的数量。

示例 1:

输入:isConnected = [[1,1,0],[1,1,0],[0,0,1]]
输出:2

示例 2:

输入:isConnected = [[1,0,0],[0,1,0],[0,0,1]]
输出:3

提示:

1 <= n <= 200
n == isConnected.length
n == isConnected[i].length
isConnected[i][j] 为 1 或 0
isConnected[i][i] == 1
isConnected[i][j] == isConnected[j][i]

代码初始模板:

class Solution {
public:
    int findCircleNum(vector<vector<int>>& isConnected) {

    }
};

超级入门级的并查集。

但是我发现并不需要查找操作,就想钻个空子三个循环解决。
思路是去点法: 两个城市如果相连就把其中一个下标大的去掉。

class Solution {
public:
    vector<int> fa;
    int findCircleNum(vector<vector<int>>& isConnected) {
        fa.resize(isConnected.size());
        for(int i = 0; i < isConnected.size(); ++i){
            fa[i] = 1;
        }
        for(int i = 0; i < isConnected.size(); ++i){
            for(int j = i+1; j < isConnected.size(); ++j){
                if(isConnected[i][j]) fa[j] = 0;
            }
        }
        int res = 0;
        for(int i = 0; i < isConnected.size(); ++i){
            res+=fa[i];
        }
        return res;
    }
};

但是这个代码会被这样的数据卡掉:
1,3相连
2,3相连
。这样2是去不掉的。

那么再增加一条规则:两个城市如果相连,如果其中一个已经去除了,就把另一个去除。
但还是能被这样的数据卡掉:
1,3相连
2,5相连
3,5相连
这样2是去不掉的。

结论:只能用并查集

class Solution {
public:
    vector<int> fa;
    int findFa(int i){
        if(fa[i] == i) return i;
        fa[i] = findFa(fa[i]);
        return fa[i];
    }
    int connect(int i, int j){
        int fa_i = findFa(i);
        int fa_j = findFa(j);
        if(fa_i < fa_j) fa[fa_j] = fa[fa_i];
        else fa[fa_i] = fa[fa_j];
        return 0;
    }
    int findCircleNum(vector<vector<int>>& isConnected) {

        fa.resize(isConnected.size());
        for(int i = 0; i < isConnected.size(); ++i){
            fa[i] = i;
        }
        for(int i = 0; i < isConnected.size(); ++i){
            for(int j = i+1; j < isConnected.size(); ++j){
                if(isConnected[i][j]) connect(i,j);
            }
        }
        int res = 0;
        for(int i = 0; i < isConnected.size(); ++i){
            if(fa[i]==i) ++res;
        }
        return res;
    }
};