解题思路

这是一道判断给定图是否为二分图的题目,主要思路如下:

  1. 二分图的定义:

    • 可以将图中的顶点分成两个不相交的集合
    • 每条边的两个顶点分别属于不同集合
    • 可以用两种颜色对顶点染色,相邻顶点颜色不同
  2. 解决方案:

    • 使用BFS进行染色
    • 从任意未染色的点开始,将其染成颜色1
    • 将其相邻点染成相反的颜色
    • 如果发现相邻点已经染色且颜色相同,则不是二分图
  3. 实现细节:

    • 使用0表示未染色
    • 使用1和2表示两种颜色
    • 需要处理图不连通的情况

代码

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int main() {
    int n, m;
    cin >> n >> m;
    
    // 构建邻接表
    vector<vector<int>> graph(n);
    vector<int> color(n, 0);  // 0表示未染色
    
    // 读入边
    for(int i = 0; i < m; i++) {
        int u, v;
        cin >> u >> v;
        graph[u-1].push_back(v-1);
        graph[v-1].push_back(u-1);
    }
    
    // BFS染色
    queue<int> q;
    for(int i = 0; i < n; i++) {
        if(color[i]) continue;  // 已染色的跳过
        
        q.push(i);
        color[i] = 1;  // 初始染色为1
        
        while(!q.empty()) {
            int u = q.front(); q.pop();
            
            // 遍历相邻节点
            for(int v : graph[u]) {
                if(color[v] == 0) {  // 未染色
                    color[v] = (color[u] == 1) ? 2 : 1;  // 染成相反的颜色
                    q.push(v);
                } else if(color[v] == color[u]) {  // 相邻节点颜色相同
                    cout << "No" << endl;
                    return 0;
                }
            }
        }
    }
    
    cout << "Yes" << endl;
    return 0;
}
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        
        // 构建邻接表
        List<List<Integer>> graph = new ArrayList<>();
        for(int i = 0; i < n; i++) {
            graph.add(new ArrayList<>());
        }
        
        // 读入边
        for(int i = 0; i < m; i++) {
            int u = sc.nextInt() - 1;
            int v = sc.nextInt() - 1;
            graph.get(u).add(v);
            graph.get(v).add(u);
        }
        
        // BFS染色
        int[] color = new int[n];
        Queue<Integer> q = new LinkedList<>();
        
        for(int i = 0; i < n; i++) {
            if(color[i] != 0) continue;
            
            q.offer(i);
            color[i] = 1;
            
            while(!q.isEmpty()) {
                int u = q.poll();
                for(int v : graph.get(u)) {
                    if(color[v] == 0) {
                        color[v] = color[u] == 1 ? 2 : 1;
                        q.offer(v);
                    } else if(color[v] == color[u]) {
                        System.out.println("No");
                        return;
                    }
                }
            }
        }
        
        System.out.println("Yes");
    }
}
from collections import deque

def is_bipartite(n, edges):
    # 构建邻接表
    graph = [[] for _ in range(n)]
    for u, v in edges:
        graph[u-1].append(v-1)
        graph[v-1].append(u-1)
    
    # BFS染色
    color = [0] * n  # 0表示未染色
    q = deque()
    
    for i in range(n):
        if color[i]: continue
        
        q.append(i)
        color[i] = 1
        
        while q:
            u = q.popleft()
            for v in graph[u]:
                if color[v] == 0:
                    color[v] = 3 - color[u]  # 1变2,2变1
                    q.append(v)
                elif color[v] == color[u]:
                    return False
    
    return True

def main():
    n, m = map(int, input().split())
    edges = []
    for _ in range(m):
        u, v = map(int, input().split())
        edges.append((u, v))
    
    print("Yes" if is_bipartite(n, edges) else "No")

if __name__ == "__main__":
    main()

算法及复杂度

  • 算法:广度优先搜索(BFS)
  • 时间复杂度: - 为节点数, 为边数
  • 空间复杂度: - 需要 color 数组和队列空间