📜  将给定的图划分为二分集

📅  最后修改于: 2022-05-13 01:56:10.435000             🧑  作者: Mango

将给定的图划分为二分集

给定一个图G(V, E) ,将它分成两个集合,使得集合中没有两个顶点直接连接。如果不可能,请打印“不可能”。

例子:

方法:这个想法是使用两个集合( UV )并以 BFS 方式遍历图。遍历每个顶点,将其标记为已访问,检查相邻顶点是否存在于集合中。如果没有,则将其插入与当前设置相反的集合中。如果是,那么如果它们在同一个集合中,则返回false。请按照以下步骤解决问题:

  • 定义一个函数bipartite()并执行以下任务:
    • 如果V等于0 ,则返回true。
    • 否则,执行 BFS 来检查邻居是否属于相反的集合。
  • 将布尔变量res初始化为true。
  • 用值false初始化向量visited[V+1]
  • 使用变量i遍历范围[1, V]并执行以下任务:
    • 如果visited[i],则将res 的值设置为resbipartite()的按位与,函数检查是否可以进行除法。
  • 执行上述步骤后,打印答案。

下面是上述方法的实现。

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Unordered sets to store ans
unordered_set sets[2];
 
// Function to divide a graph into two sets,
// returns true if possible otherwise false
bool bipartite(vector >& edges,
               int V, int i,
               vector& visited)
{
    if (V == 0) {
        return true;
    }
    vector pending;
 
    // Inserting source vertex in U(set[0])
    sets[0].insert(i);
 
    // Enqueue source vertex
    pending.push_back(i);
    while (pending.size() > 0) {
 
        // Dequeue current vertex
        int current = pending.back();
 
        // Mark the current vertex true
        visited[current] = true;
        pending.pop_back();
 
        // Finding the set of
        // current vertex(parent vertex)
        int currentSet
            = sets[0].count(current)
                      > 0
                  ? 0
                  : 1;
        for (int i = 0; i
                        < edges[current].size();
             i++) {
 
            // Picking out neighbour
            // of current vertex
            int neighbor = edges[current][i];
 
            // If not present
            // in any of the set
            if (sets[0].count(neighbor) == 0
                && sets[1].count(neighbor) == 0) {
 
                // Inserting in opposite
                // of current vertex
                sets[1 - currentSet].insert(neighbor);
                pending.push_back(neighbor);
            }
 
            // Else if present in the same
            // current vertex set the partition
            // is not possible
            else if (sets[currentSet].count(neighbor)
                     > 0) {
                return false;
            }
        }
    }
 
    return true;
}
 
bool possibleBipartition(int V,
                         vector >& G)
{
 
    // To store graph as adjacency list in edges
    vector > edges(V + 1);
    for (auto v : G) {
        edges[v[0]].push_back(v[1]);
        edges[v[1]].push_back(v[0]);
    }
 
    vector visited(V + 1, false);
    bool res = true;
    for (int i = 1; i <= V; i++) {
        if (!visited[i]) {
            res = res and bipartite(edges, V,
                                    i, visited);
        }
    }
    return res;
}
 
// Driver Code
int main()
{
    int V = 7, E = 6;
    vector > G
        = { { 1, 2 }, { 2, 3 }, { 3, 4 },
            { 3, 6 }, { 5, 6 }, { 6, 7 } };
 
    // If partition is possible
    if (possibleBipartition(V, G)) {
        for (auto elem : sets[0]) {
            cout << elem << " ";
        }
        cout << "\n";
        for (auto elem : sets[1]) {
            cout << elem << " ";
        }
    }
 
    // If partition is not possible
    else
        cout << "Not Possible";
 
    return 0;
}


输出
7 5 1 3 
6 2 4 

时间复杂度: O(N)
辅助空间: O(N)