当前位置: 首页 > news >正文

二分图判定算法

二分图判定算法

  • 判断二分图
    • dfs遍历
    • bfs遍历
  • 可能的二分法
    • bfs遍历
    • dfs遍历

二分图判定说白了就是遍历一遍图,一边遍历一边染色,看看能不能用两种颜色给所有节点染色,且相邻节点的颜色都不相同。

// 图遍历框架dfs
var traverse = function(graph, visited, v) {
    visited[v] = true;
    // 遍历节点 v 的所有相邻节点 neighbor
    for (var neighbor of graph.neighbors(v)) {
        if (!visited[neighbor]) {
            // 相邻节点 neighbor 没有被访问过
            // 那么应该给节点 neighbor 涂上和节点 v 不同的颜色
            traverse(graph, visited, neighbor);
        } else {
            // 相邻节点 neighbor 已经被访问过
            // 那么应该比较节点 neighbor 和节点 v 的颜色
            // 若相同,则此图不是二分图
        }
    }
}

判断二分图

链接在这里插入图片描述

dfs遍历

class Solution {
    //用dfs遍历一遍图
    boolean res=true;
    boolean []visit;//保证每个节点只当一次start向四周染色
    boolean []col;
    public boolean isBipartite(int[][] graph) {
        int sz=graph.length;//节点的个数
        visit=new boolean[sz];
        col=new boolean[sz];
        for(int i=0;i<sz;i++){
            if(!visit[i]){
                dfs(graph,i);
            }
        }
        return res;
    }
    
    void dfs(int[][]graph,int start){
        if(res==false){
            return;
        }
   
        visit[start]=true;
        for(int neibor:graph[start]){
            if(!visit[neibor]){
                //染色
                col[neibor]=!col[start];
                dfs(graph,neibor);
            }else{
                //判断
                if(col[neibor]==col[start]){
                    res=false;
                    return;
                }
            }
        }
    }
}

bfs遍历

class Solution {
    public boolean isBipartite(int[][] graph) {
        int n=graph.length;
        boolean[]visit=new boolean[n];//记录进队列的节点,保证每个节点只进一次,进一次就相当于以这个节点为start了向四周染色了
        boolean[]col=new boolean[n];
        Queue<Integer> q=new LinkedList();
        for(int i=0;i<n;i++){
            if(visit[i]){
                continue;
            }
            //从i开始bfs
            q.add(i);
            visit[i]=true;
            while(!q.isEmpty()){
                int cur=q.poll();
                for(int neibor:graph[cur]){
                    if(!visit[neibor]){
                        //染色
                        col[neibor]=!col[cur];
                        q.add(neibor);
                        visit[neibor]=true;
                    }else{
                        //检查
                        if(col[neibor]==col[cur]){
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }
}

可能的二分法

链接
在这里插入图片描述

bfs遍历

class Solution {
    //染过颜色就visit标记一下,然后进队列,进了队列就一定会出队列,出队列就会以它为中心向四周染色,visit[i]为真代表以i为中心向四周染色过
    public boolean possibleBipartition(int n, int[][] dislikes) {
        //先创建图,然后将图染色
        List<Integer>[]graph=new LinkedList[n+1];
        for(int i =1;i<=n;i++){
            graph[i]=new LinkedList();
        }
        for(int []e:dislikes){
            int a=e[0];
            int b=e[1];
            graph[a].add(b);
            graph[b].add(a);
        }
        boolean[]visit=new boolean[n+1];
        Queue<Integer> q=new LinkedList();
        boolean[]col=new boolean[n+1];
        for(int i=1;i<=n;i++){
            if(visit[i]){
                continue;
            }
            
            q.add(i);
            visit[i]=true;
            while(!q.isEmpty()){
                int cur=q.poll();
                for(int neibor:graph[cur]){
                    if(!visit[neibor]){
                        //染色
                        col[neibor]=!col[cur];
                        q.add(neibor);
                        visit[neibor]=true;
                    }else{
                        //判断
                        if(col[neibor]==col[cur]){
                            return false;
                        }
                    }
                }
            }

        }
        return true;
    }
}

dfs遍历

class Solution {
    boolean[]col;
    boolean[]visit;//保证了每个节点都当过start一次,向四周染色
    boolean isBi=true;
    public boolean possibleBipartition(int n, int[][] dislikes) {
        //先创建图,然后将图染色
        List<Integer>[]graph=new LinkedList[n+1];
        for(int i =1;i<=n;i++){
            graph[i]=new LinkedList();
        }
        for(int []e:dislikes){
            int a=e[0];
            int b=e[1];
            graph[a].add(b);
            graph[b].add(a);
        }
        visit=new boolean[n+1];//visit[i]=true说明 以i为start向四周染色过
        col=new boolean[n+1];
        for(int i=1;i<=n;i++){
            if(!visit[i]){//没有以i为start过
                dfs(graph,i);
            }
            if(isBi==false){
                return false;
            }
        }
        return true;
    }
    //定义:从start开始遍历图,一边遍历一边涂色
    void dfs(List<Integer>[]graph,int start){
        if(!isBi){
            //已经知道不是二分图
            return;
        }
      
        visit[start]=true;
        for(int neibor:graph[start]){
            if(!visit[neibor]){
               //涂色
               col[neibor]=!col[start];
               dfs(graph,neibor);
            }else{
                if(col[neibor]==col[start]){
                    isBi=false;
                    return;
                }
            }
        }
    }
}

相关文章:

  • CFD计算中如何应对cell aspect ratio比例严重失调情况
  • 第一章,网络发展史
  • LangChain组件Tools/Toolkits详解(7)——工具调用与Toolkits
  • Java线程池深度解析:从使用到调优
  • QT笔记---JSON
  • 高并发库存系统是否适合使用 ORM(Hibernate / MyBatis)
  • kafka压缩
  • 从0到1在windows上用flutter开发android app(环境准备、创建项目、加速构建)
  • Linux环境变量:深入解析与实用指南
  • 软件上线倒计时,测试团队如何量化风险优先级?
  • 本地基于Ollama部署的DeepSeek详细接口文档说明
  • 【dify】 dify环境变量配置说明
  • AI智能问答“胡说八道“-RAG探索之路
  • 微信小程序使用状态管理 - mobx-miniprogram
  • 打破同源策略:前端跨域的全面解析与应对策略
  • MIPI 详解:XAPP894 D-PHY Solutions
  • 深入理解Java的 JIT(即时编译器)
  • 操作系统(第三章 内存管理)
  • 计算机三级网络技术知识汇总【10】
  • AtCoderABC387题解
  • 央行设立服务消费与养老再贷款,额度5000亿元
  • 稳住外贸基本盘,这个中部大省出手了
  • 读图|展现城市品格,上海城市影像走进南美
  • 经济日报整版聚焦“妈妈岗”:就业路越走越宽,有温度重实效
  • 苹果Safari浏览器上的搜索量首次下降
  • 东亚社会的“苦难诗学”:从《苦尽柑来遇见你》说起