简体   繁体   English

使用 dfs 检查图是否为二部图

[英]using dfs to check if graph is bipartite


class graph{
    void DFSutil(int v);

    public:
        
        map<int, vector<int> > adj;
        map<int, bool> visited;
        map<int, int> color;
        int twoteams = 1;
        
        void DFS();
        void addEdge(int u,int v);
        
        
};

this function adds edge to the graph此函数为图形添加边


void graph::addEdge(int u,int v){
    
    adj[u].push_back(v);
    
}

depth first search function.深度优先搜索功能。 i tried to color the child as !parent (in case im not wrong): and if the color of child and parent is same, that means the graph is not bipartite我试图将孩子着色为 !parent (以防我没有错):如果孩子和父母的颜色相同,这意味着该图不是二部图


void graph::DFSutil(int v){
    
    visited[v] = true;
    
    for (auto i:adj[v]){
        if(visited[i]==false){
            
            color[i] = !color[v];
            DFSutil(i);
            
        }
        else if(color[i]==color[v]){
            
        twoteams = 0;
        return;
        }
    }
}

in case the graph has more than one connected component如果图有多个连通分量

void graph::DFS(){
    
    for (auto i:adj){
        if(!visited[i.first]) DFSutil(i.first);
    }
    
}

the graph is given as: B (a vector): [[1,2],[1,3]...] the edges: 1-->2, 1-->3...该图给出为:B(向量):[[1,2],[1,3]...] 边:1-->2, 1-->3...

int Solution::solve(int A, vector<vector<int> > &B) {
    
    graph g;
    g.addEdge(B[0][0],B[0][1]);
    g.color[B[0][0]] = 1;
    int n = B.size();
    for (int i=1;i<n;++i){
        
        g.addEdge(B[i][0],B[i][1]);
        
    }
    g.DFS();
    return g.twoteams;
}

why does it not check if the graph is bipartite.为什么它不检查图形是否是二部图。 color stores the color of a node as 0 or 1; color 将节点的颜色存储为 0 或 1; it should return 0 if not bipartite and 1 otherwise如果不是双向的,则返回 0,否则返回 1

To determine if a graph is bipartite it is sufficient to determine that the number of maximal cliques is exactly two.为了确定一个图是否是二部图,确定最大集团的数量正好是两个就足够了。

Here is the pseudo code for finding the maximal cliques这是查找最大团的伪代码

LOOP
    CONSTRUCT empty current set
    SELECT V arbitrary vertex
    add V to current set
    remove V from graph
    LOOP      // while set is growing
        added_to_set = false
        LOOP V over vertices in graph
            LOOP Vset over current set
                IF Vset connected to V
                     add V to current set
                     remove V from graph
                     added_to_set = true
                     break;
        IF added_to_set == false
           break;    // the set is maximal
    ADD current set to list of sets
    IF graph has no remaining vertices
       OUTPUT sets found
       STOP

For a C++ implementation of this see code at https://github.com/JamesBremner/PathFinder2/blob/dbd6ff06edabd6a6d35d5eb10ed7972dc2d779a6/src/cPathFinder.cpp#L483有关此的 C++ 实现,请参阅https://github.com/JamesBremner/PathFinder2/blob/dbd6ff06edabd6a6d35d5eb10ed7972dc2d779a6/src/cPathFinder.cpp#L483 上的代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM