1. 程式人生 > >二分圖判斷-筆試題

二分圖判斷-筆試題

不同 解析 string code max c++ include href ons

  • 第四範式秋招筆試題

題目

- 給定一個具有n個頂點的圖。要給圖上每個頂點染色,並且要使相鄰的頂點顏色不同。判斷是否能最多用兩種顏色進行染色。題目保證沒有重邊和自環。
 
  • 概念:把相鄰頂點染成不同顏色的問題叫做圖的著色問題。對圖進行染色所需要的最小顏色數稱為最小著色度。最小著色度為2的圖稱作二分圖。

  • 分析:如果只用兩種顏色,那麽確定一個頂點的顏色之後,和它相鄰的頂點的顏色也就確定了。因此,選擇任意一個頂點出發,依次確定相鄰頂點的顏色,就可以判斷是否可以被2種顏色染色了。這個問題用深度優先搜索可以簡單實現。

解析

// 一個簡單的二分圖的判斷
 
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
 
const int MAX_N =105;
int V,E;
// 使用鄰接表模擬一張無向圖
vector<int> G[MAX_N];
// 頂點的顏色,初始化為0,上色有兩種顏色(0 or 1)
int color[MAX_N];
 
bool dfs(int v, int c)
{
    color[v] = c;       // 把頂點染成c
    for(int i = 0; i < G[v].size(); i++)
    {
        // 如果當前點的相鄰的點同色就返回false
        if(color[G[v][i]] == c)
            return false;
        // 如果當前點的鄰點還沒被染色,就染成-c
        if(color[G[v][i]] == 0 && !dfs(G[v][i], -c))
            return false;
    }
    // 如果當前點都被染過色,就返回true
    return true;
}
 
void solve()
{
    for(int i = 0; i < V; i++)
    {
        if(color[i] == 0)
        {
            if(!dfs(i,1))
            {
                cout << "no" << endl;
                return;
            }
        }
    }
    cout << "yes" << endl;
}
 
int main()
{
    cin >> V >> E;
    for(int i = 0; i < E;  i++)
    {
        int s, t;
        cin >> s >> t;
        G[s].push_back(t);
        G[t].push_back(s);  // 如果有向圖則無需這一句
    }
    memset(color, 0, sizeof(color));
    solve();
 
    return 0;
}

參考

  • NYOJ-1015(判斷是否為二分圖)
  • 二分圖的判斷 bfs+dfs兩種搜索方法判斷

二分圖判斷-筆試題