[三星电子]算法题--两种颜色涂无向图(bfs)

题目

题目描述: 给一无向图中各个节点绘色,一共只有两种颜色,使其满足相邻节点颜色不同,并输出其中一种颜色的节点个数及序号;如果不满足,则输出-1。

示例:

第一行输入节点个数V和边数E,第二行输入E条边(每条边对应的两个节点),例如:

7 9

1 2 1 4 2 3 3 4 2 5 4 5 2 6 5 7 6 7

例图:

代码与解析

这个算法的目的是检测一个给定的图是否包含一个二分图。二分图是一种特殊的图,它的顶点集可以被划分为两个互不相交的子集,使得每条边的两个顶点都属于不同的子集。

算法的基本思路是使用广度优先搜索(BFS) 来遍历图,同时维护一个颜色数组来标记每个节点的颜色。如果图中存在一个二分图,那么存在一个节点,其所有邻接节点都与它颜色不同。如果图中不存在二分图,那么存在一个节点,其所有邻接节点都与它颜色相同。

具体步骤如下:

  1. 初始化一个队列和一个标志位。队列用于存储待处理的节点,标志位用于检测是否找到了二分图。

  2. 将起始节点加入队列,并将其颜色设为1(假设开始时所有节点都是白色)。

  3. 进入循环,直到队列为空:

    • 从队列中取出一个节点,并检查其所有未被处理的邻接节点。
    • 如果某个邻接节点未被处理且颜色与当前节点不同,将其颜色设为与当前节点颜色相反的颜色,并将其加入队列。
    • 如果某个邻接节点未被处理且颜色与当前节点相同,将标志位设为true并跳出循环。
  4. 如果循环结束时标志位仍为false,说明图中存在一个二分图。否则,图中不存在二分图。

  5. 如果图中存在二分图,计算并输出属于同一子集的节点数。

  6. 如果图中不存在二分图,输出节点的数量。

这个算法的时间复杂度是O(V + E),其中V是顶点数,E是边数。这是因为每个顶点和边都只会被访问和处理一次。

java 复制代码
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Nodirections {
    static int[][] a = new int[1001][1001]; // 存储图的邻接关系
    // 0为默认白色,1代表黑色,同时[0]代表颜色为?[1]代表是否被设置
    static int[][] color = new int[1001][2]; // 记录节点的颜色和状态
    static int[] num = new int[1001]; // 记录黑色节点的编号
    static int num1 = 0; // 记录黑色节点数量

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int v, e;
        System.out.println("请输入节点数和边数: ");
        v = in.nextInt(); // 读取节点数
        e = in.nextInt(); // 读取边数
        for (int i = 0; i < e; i++) {
            int x = in.nextInt();
            int y = in.nextInt();
            a[x][y] = 1;
            a[y][x] = 1; // 无向图,设置两个方向的邻接关系
        }
        Queue<Integer> q = new LinkedList<>();
        q.add(1); // 添加第一个节点1
        boolean b = false; // 记录是否出现颜色冲突
        while (!q.isEmpty()) {
            int curV = q.poll();
            int temp = color[curV][0]; // 当前节点的颜色
            color[curV][1] = 2; // 设置节点状态为已遍历
            for (int j = 1; j <= v; j++) {
                if (a[curV][j] == 0) continue; // 无邻接关系,跳过
                // j节点与cur节点连通并且颜色未被设置
                if (color[j][1] == 0) {
                    color[j][0] = 1 - temp; // 颜色取反
                    color[j][1] = 2; // 设置节点状态
                    q.add(j);
                }
                if (color[j][1] == 2) {
                    if (color[j][0] != (1 - temp)) {
                        b = true;
                        break;
                    }
                }
            }
            if (b) {
                num1 = -1; // 出现颜色冲突,标记为-1
                break;
            }
        }
        if (!b) {
            num1 = 0;
            for (int k = 1; k <= v; k++) {
                if (color[k][0] == 1) {
                    num[num1++] = k; // 记录黑色节点的编号
                }
            }
        }
        System.out.print("#:" + num1); // 输出黑色节点的数量
        for (int d = 0; d < num1; d++) {
            System.out.print(" " + num[d]); // 输出黑色节点的编号
        }
        System.out.println();
    }
}
相关推荐
弹简特几秒前
【JavaEE05-后端部分】使用idea社区版从零开始创建第一个 SpringBoot 程序
java·spring boot·后端
爬山算法4 分钟前
Hibernate(81)如何在数据同步中使用Hibernate?
java·后端·hibernate
Ivanqhz37 分钟前
现代异构高性能计算(HPC)集群节点架构
开发语言·人工智能·后端·算法·架构·云计算·边缘计算
Loo国昌39 分钟前
【大模型应用开发】第三阶段:深度解析检索增强生成(RAG)原理
人工智能·后端·深度学习·自然语言处理·transformer
Demon_Hao1 小时前
Spring Boot开启虚拟线程ScopedValue上下文传递
java·spring boot·后端
小高Baby@1 小时前
ShouldBind、ShouldBindJson、ShouldBindQuery的区别
后端·golang
BYSJMG1 小时前
计算机毕设选题推荐:基于Hadoop的交通事故数据可视化分析系统
大数据·vue.js·hadoop·分布式·后端·信息可视化·课程设计
野犬寒鸦1 小时前
从零起步学习并发编程 || 第三章:JMM(Java内存模型)详解及对比剖析
java·服务器·开发语言·分布式·后端·学习·spring
沐泽__1 小时前
Flask简介
后端·python·flask
半聋半瞎1 小时前
Flowable快速入门(Spring Boot整合版)
java·spring boot·后端·flowable