• 886.可能的二分法 | 785.判断二分图


    785.判断二分图

    存在一个 无向图 ,图中有 n 个节点。其中每个节点都有一个介于 0 到 n - 1 之间的唯一编号。给你一个二维数组 graph ,其中 graph[u] 是一个节点数组,由节点 u 的邻接节点组成。形式上,对于 graph[u] 中的每个 v ,都存在一条位于节点 u 和节点 v 之间的无向边。该无向图同时具有以下属性:
    不存在自环(graph[u] 不包含 u)。
    不存在平行边(graph[u] 不包含重复值)。
    如果 v 在 graph[u] 内,那么 u 也应该在 graph[v] 内(该图是无向图)
    这个图可能不是连通图,也就是说两个节点 u 和 v 之间可能不存在一条连通彼此的路径。
    二分图 定义:如果能将一个图的节点集合分割成两个独立的子集 A 和 B ,并使图中的每一条边的两个节点一个来自 A 集合,一个来自 B 集合,就将这个图称为 二分图 。

    如果图是二分图,返回 true ;否则,返回 false 。

    示例 1:


    输入:graph = [[1,2,3],[0,2],[0,1,3],[0,2]]
    输出:false
    解释:不能将节点分割成两个独立的子集,以使每条边都连通一个子集中的一个节点与另一个子集中的一个节点。

    思路:(双色问题)遍历一遍图,一边遍历一边染色,看看能不能用两种颜色给所有节点染色,且相邻节点的颜色都不相同。 

    1. class Solution {
    2. public:
    3. bool res=true;
    4. vector<bool> visited;
    5. vector<bool> color;
    6. bool isBipartite(vectorint>>& graph)
    7. {
    8. color.resize(graph.size());
    9. visited.resize(graph.size());
    10. for(int i=0;isize();i++)
    11. {
    12. if(!visited[i])
    13. {
    14. traverse(graph,i);
    15. }
    16. }
    17. return res;
    18. }
    19. void traverse(vectorint>>& graph,int i)
    20. {
    21. if(visited[i])
    22. return ;
    23. visited[i]=true;
    24. for(int j:graph[i])
    25. {
    26. if(!visited[j])//如果i的相邻结点j没有被遍历过,那么就染上和j不同的颜色,继续遍历
    27. {
    28. color[j]=!color[i];
    29. traverse(graph,j);
    30. }
    31. else//如果j被遍历过了,那么就判断下它和i的颜色是否相同,如果相同,那么就不是二分图
    32. {
    33. if(color[j]==color[i])
    34. {
    35. res=false;
    36. return ;
    37. }
    38. }
    39. }
    40. }
    41. };

     

     886.可能的二分法

    给定一组 n 人(编号为 1, 2, ..., n), 我们想把每个人分进任意大小的两组。每个人都可能不喜欢其他人,那么他们不应该属于同一组。

    给定整数 n 和数组 dislikes ,其中 dislikes[i] = [ai, bi] ,表示不允许将编号为 ai 和  bi的人归入同一组。当可以用这种方法将所有人分进两组时,返回 true;否则返回 false。

    示例 1:

    输入:n = 4, dislikes = [[1,2],[1,3],[2,4]]
    输出:true
    解释:group1 [1,4], group2 [2,3]

    思路:把 dislikes 构造成一幅图(无向图,因为两人相互讨厌),然后执行二分图的判定算法 

    把每个人看做图中的节点,相互讨厌的关系看做图中的边,由 dislikes 数组就可以构成一幅图;又因为题目说互相讨厌的人不能放在同一组里,相当于图中的所有节点都要放进两个不同的组;那就回到了「双色问题」,如果能够用两种颜色着色所有节点,且相邻节点颜色都不同,那么按照颜色把这些节点分成两组就ok了。

    1. class Solution {
    2. public:
    3. bool res=true;
    4. vector<bool> visited;
    5. vector<bool> color;
    6. bool possibleBipartition(int n, vectorint>>& dislikes)
    7. {
    8. color.resize(n);
    9. visited.resize(n);
    10. vectorint>> graph;
    11. graph.resize(n);
    12. for(vector<int> edge:dislikes)//建立无向图的邻接表
    13. {
    14. int from=edge[0]-1;
    15. int to=edge[1]-1;
    16. graph[from].push_back(to);
    17. graph[to].push_back(from);
    18. }
    19. for(int i=0;i//遍历图的每一个结点,执行二分图判定
    20. {
    21. if(!visited[i])
    22. {
    23. traverse(graph,i);
    24. }
    25. }
    26. return res;
    27. }
    28. void traverse(vectorint>>& graph,int i)
    29. {
    30. if(visited[i])
    31. return ;
    32. visited[i]=true;
    33. for(int j:graph[i])
    34. {
    35. if(!visited[j])//j是i的相邻结点且j没有被遍历过,就让j取i相反的颜色,继续遍历
    36. {
    37. color[j]=!color[i];
    38. traverse(graph,j);
    39. }
    40. else//j是i的相邻结点且j被遍历过了
    41. {
    42. if(color[j]==color[i])//判断j和i颜色是否相同,相同就不是二分图
    43. {
    44. res=false;
    45. return;
    46. }
    47. }
    48. }
    49. }
    50. };
  • 相关阅读:
    华为云云耀云服务器L实例评测|部署功能强大的办公套件 ONLYOFFICE
    Mono创始人 Miguel de Icaza今天离开微软
    LeetCode | 876. Middle of the Linked List
    MyBatis(二)
    Linux C/C++ UDP Socket 网络通信
    C语言中整型与浮点型在内存中的存储
    React中的Hooks--useReducer()
    爬虫异常处理实战:应对请求频率限制和数据格式异常
    怎么压缩PDF文件大小?不会操作的快看过来
    OPPO realme 真我 一加 刷机工具下载 ColorOS Upgrade Tool
  • 原文地址:https://blog.csdn.net/weixin_50437588/article/details/126295004