785. 判断二分图[并查集][染色法]

785. 判断二分图

By Jalan

文章目录

  • [785. 判断二分图](https://leetcode-cn.com/problems/is-graph-bipartite)
  • **By Jalan**
  • 知识工具需求
    • 数据结构和算法
  • 题干
  • 题解
    • 第一次
      • 思路
      • 编写用时
      • 代码
        • CPP
          • 运行用时
  • 结尾

知识工具需求

数据结构和算法

  • 并查集

题干

给定一个无向图graph,当这个图为二分图时返回true。
如果我们能将一个图的节点集合分割成两个独立的子集A和B,并使图中的每一条边的两个节点一个来自A集合,一个来自B集合,我们就将这个图称为二分图。
graph将会以邻接表方式给出,graph[i]表示图中与节点i相连的所有节点。每个节点都是一个在0到graph.length-1之间的整数。这图中没有自环和平行边: graph[i] 中不存在i,并且graph[i]中没有重复的值。

题解

第一次

思路

观看二分图的性质,显然有:二分图把图的定点分成两个子集,每个子集之内的元素要求不能有连通到本集合内部的边.
设最终的二分点集是 G 1 , G 2 G_1,G_2 G1,G2
所以边是我们区分点集的手段,对于一个节点i,假设i在点集 G 1 G_1 G1内,那么和他有边的节点集合 S i S_i Si G 2 G_2 G2的一个子集.
我们依次遍历节点和它的边,检查每个边的另一个端点的集合,假如和i节点的集合一致(root一致),那么就不能二分( G 1 ∣ ∣ G 2 G_1||G_2 G1G2内部出现了边)
每条边在遍历中会出现2次,因此不用担心出现遗漏的情况
另外,如果统计并查集中最终集合的数量,可能是会大于2的.但是这种多集合的情况也满足二分图的性质(可以任意合并2个集合直到剩余两个集合,这两个集合也满足二分图的性质)

编写用时

20分钟

代码

CPP

#include 
#include 
using namespace std;
class Solution
{
     
public:
    vector<int> parent;
    int findRoot(int x)
    {
     
        int oriX = x;
        while (parent[x] != x)
        {
     
            x = parent[x];
        }
        while (parent[oriX] != x)
        {
     
            int temp = parent[oriX];
            parent[oriX] = x;
            oriX = temp;
        }
        return x;
    }
    void unionNode(int sun, int father)
    {
     
        parent[sun] = father;
        return;
    }
    bool isBipartite(vector<vector<int>> &graph)
    {
     
        int size = graph.size();
        //initalize
        parent.resize(size);
        for (int i = 0; i < size; i++)
        {
     
            parent[i] = i;
        }
        //
        for (int i = 0; i < size; i++)
        {
     
            int roota = findRoot(i);
            int edgeSize = graph[i].size();
            if (edgeSize > 0)
            {
     
                int rootb = findRoot(graph[i][0]);
                if (rootb == roota)
                {
     
                    return false;
                }
                for (int j = 1; j < edgeSize; j++)
                {
     
                    int rootc = findRoot(graph[i][j]);
                    if (findRoot(graph[i][j]) == roota)
                    {
     
                        return false;
                    }
                    unionNode(rootc, rootb);
                }
            }
        }
        return true;
    }
};

int main(int argc, char const *argv[])
{
     

    return 0;
}
运行用时

在这里插入图片描述

结尾

看在我写了这么多注释的份上可以给我点个赞嘛,求求惹=]砰砰砰,给我加点写下去的油呀
@.@
也欢迎关注我的CSDN账号呀=]

                                        **开心code每一天**

你可能感兴趣的:(LeetCode中等,染色法题目,并查集题目)