📜  两个集团问题(检查图形是否可以分为两个集团)

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

两个集团问题(检查图形是否可以分为两个集团)

Clique 是图的子图,使得子图中的所有顶点彼此完全连接。给定一个 Graph,判断它是否可以分成两个 Clique。

例子:

Input : G[][] =   {{0, 1, 1, 0, 0},
                  {1, 0, 1, 1, 0},
                  {1, 1, 0, 0, 0},
                  {0, 1, 0, 0, 1},
                  {0, 0, 0, 1, 0}};
Output : Yes

图分为两个派系

这个问题起初看起来很棘手,但有一个简单而有趣的解决方案。如果一个图的补图是二分图,则该图可以分为两个团。所以下面是两个步骤来确定图形是否可以分成两个集团。

  • 求 Graph 的补码。下面是补图,上面显示的图。作为补充,所有原始边缘都被删除。并且它们之间没有边的顶点现在有一条边连接它们。

两个集团2

  • 如果补码是二分的,则返回 true,否则返回 false。上图是二分图。此处讨论了检查 Graph 是否为 Bipartite。

这是如何运作的?
如果补码是二分图,则图可以分为两个集合 U 和 V,使得没有边连接到同一集合的顶点。这意味着在原始图中,这些集合 U 和 V 是完全连通的。因此,原始图可以分为两个派系。

执行:
下面是上述步骤的实现。

C++
// C++ program to find out whether a given graph can be
// converted to two Cliques or not.
#include 
using namespace std;
 
const int V = 5;
 
// This function returns true if subgraph reachable from
// src is Bipartite or not.
bool isBipartiteUtil(int G[][V], int src, int colorArr[])
{
    colorArr[src] = 1;
 
    // Create a queue (FIFO) of vertex numbers and enqueue
    // source vertex for BFS traversal
    queue  q;
    q.push(src);
 
    // Run while there are vertices in queue (Similar to BFS)
    while (!q.empty())
    {
        // Dequeue a vertex from queue
        int u = q.front();
        q.pop();
 
        // Find all non-colored adjacent vertices
        for (int v = 0; v < V; ++v)
        {
            // An edge from u to v exists and destination
            // v is not colored
            if (G[u][v] && colorArr[v] == -1)
            {
                // Assign alternate color to this adjacent
                // v of u
                colorArr[v] = 1 - colorArr[u];
                q.push(v);
            }
 
            // An edge from u to v exists and destination
            // v is colored with same color as u
            else if (G[u][v] && colorArr[v] == colorArr[u])
                return false;
        }
    }
 
    // If we reach here, then all adjacent vertices can
    // be colored with alternate color
    return true;
}
 
// Returns true if a Graph G[][] is Bipartite or not. Note
// that G may not be connected.
bool isBipartite(int G[][V])
{
    // Create a color array to store colors assigned
    // to all vertices. Vertex number is used as index in
    // this array. The value '-1' of  colorArr[i]
    // is used to indicate that no color is assigned to
    // vertex 'i'.  The value 1 is used to indicate first
    // color is assigned and value 0 indicates
    // second color is assigned.
    int colorArr[V];
    for (int i = 0; i < V; ++i)
        colorArr[i] = -1;
 
    // One by one check all not yet colored vertices.
    for (int i = 0; i < V; i++)
        if (colorArr[i] == -1)
            if (isBipartiteUtil(G, i, colorArr) == false)
                return false;
 
    return true;
}
 
// Returns true if G can be divided into
// two Cliques, else false.
bool canBeDividedinTwoCliques(int G[][V])
{
    // Find complement of G[][]
    // All values are complemented except
    // diagonal ones
    int GC[V][V];
    for (int i=0; i


Java
// Java program to find out whether a given graph can be
// converted to two Cliques or not.
import java.util.ArrayDeque;
import java.util.Deque;
class GFG {
static int V = 5;
  
// This function returns true if subgraph reachable from
// src is Bipartite or not.
static boolean isBipartiteUtil(int G[][], int src, int colorArr[])
{
    colorArr[src] = 1;
  
    // Create a queue (FIFO) of vertex numbers and enqueue
    // source vertex for BFS traversal
    Deque  q = new ArrayDeque<>();
    q.push(src);
  
    // Run while there are vertices in queue (Similar to BFS)
    while (!q.isEmpty())
    {
        // Dequeue a vertex from queue
        int u = q.peek();
        q.pop();
  
        // Find all non-colored adjacent vertices
        for (int v = 0; v < V; ++v)
        {
            // An edge from u to v exists and destination
            // v is not colored
            if (G[u][v] == -1 && colorArr[v] == -1)
            {
                // Assign alternate color to this adjacent
                // v of u
                colorArr[v] = 1 - colorArr[u];
                q.push(v);
            }
  
            // An edge from u to v exists and destination
            // v is colored with same color as u
            else if (G[u][v] == colorArr[u] && colorArr[v] == colorArr[u])
                return false;
        }
    }
  
    // If we reach here, then all adjacent vertices can
    // be colored with alternate color
    return true;
}
  
// Returns true if a Graph G[][] is Bipartite or not. Note
// that G may not be connected.
static boolean isBipartite(int G[][])
{
    // Create a color array to store colors assigned
    // to all vertices. Vertex number is used as index in
    // this array. The value '-1' of  colorArr[i]
    // is used to indicate that no color is assigned to
    // vertex 'i'.  The value 1 is used to indicate first
    // color is assigned and value 0 indicates
    // second color is assigned.
    int colorArr[]=new int[V];
    for (int i = 0; i < V; ++i)
        colorArr[i] = -1;
  
    // One by one check all not yet colored vertices.
    for (int i = 0; i < V; i++)
        if (colorArr[i] == -1)
            if (isBipartiteUtil(G, i, colorArr) == false)
                return false;
  
    return true;
}
  
// Returns true if G can be divided into
// two Cliques, else false.
static boolean canBeDividedinTwoCliques(int G[][])
{
    // Find complement of G[][]
    // All values are complemented except
    // diagonal ones
    int GC[][]=new int[V][V];
    for (int i=0; i


Python3
# Python3 program to find out whether a given
# graph can be converted to two Cliques or not.
from queue import Queue
 
# This function returns true if subgraph
# reachable from src is Bipartite or not.
def isBipartiteUtil(G, src, colorArr):
    global V
    colorArr[src] = 1
 
    # Create a queue (FIFO) of vertex numbers
    # and enqueue source vertex for BFS traversal
    q = Queue()
    q.put(src)
 
    # Run while there are vertices in
    # queue (Similar to BFS)
    while (not q.empty()):
         
        # Dequeue a vertex from queue
        u = q.get()
 
        # Find all non-colored adjacent vertices
        for v in range(V):
             
            # An edge from u to v exists and
            # destination v is not colored
            if (G[u][v] and colorArr[v] == -1):
                 
                # Assign alternate color to this 
                # adjacent v of u
                colorArr[v] = 1 - colorArr[u]
                q.put(v)
 
            # An edge from u to v exists and destination
            # v is colored with same color as u
            elif (G[u][v] and colorArr[v] == colorArr[u]):
                return False
 
    # If we reach here, then all adjacent
    # vertices can be colored with alternate color
    return True
 
# Returns true if a Graph G[][] is Bipartite or not.
# Note that G may not be connected.
def isBipartite(G):
    global V
     
    # Create a color array to store colors assigned
    # to all vertices. Vertex number is used as index 
    # in this array. The value '-1' of colorArr[i]
    # is used to indicate that no color is assigned
    # to vertex 'i'. The value 1 is used to indicate
    # first color is assigned and value 0 indicates
    # second color is assigned.
    colorArr = [-1] * V
 
    # One by one check all not yet
    # colored vertices.
    for i in range(V):
        if (colorArr[i] == -1):
            if (isBipartiteUtil(G, i, colorArr) == False):
                return False
 
    return True
 
# Returns true if G can be divided into
# two Cliques, else false.
def canBeDividedinTwoCliques(G):
    global V
     
    # Find complement of G[][]
    # All values are complemented
    # except diagonal ones
    GC = [[None] * V for i in range(V)]
    for i in range(V):
        for j in range(V):
            GC[i][j] = not G[i][j] if i != j else 0
 
    # Return true if complement is 
    # Bipartite else false.
    return isBipartite(GC)
 
# Driver Code
V = 5
 
G = [[0, 1, 1, 1, 0],
     [1, 0, 1, 0, 0],
     [1, 1, 0, 0, 0],
     [0, 1, 0, 0, 1],
     [0, 0, 0, 1, 0]]
 
if canBeDividedinTwoCliques(G):
    print("Yes")
else:
    print("No")
 
# This code is contributed by PranchalK


输出 :

Yes

上述实现的时间复杂度为 O(V 2 )。

参考:
http://math.stackexchange.com/questions/310092/the-two-clique-problem-is-in-p-or-np-p-np-for-hypothesis