如何在给定图中找到最大的双分子图?

时间:2018-06-07 05:20:37

标签: graph depth-first-search bipartite subgraph cyclic

给定一个无向的未加权图:它可能是循环的,每个顶点都有值,如图所示。

Original Graph

查找最大Bi-Partite子图的大小(最大值表示该图中最大顶点数(已连接))?

答案:

The solution is shown here

最大的图表是橙色的,所以答案是8。

我的方法:

#define loop(i,n) for(int i=0;i<n;i++)                                    
int vis[N+1];
vector<int> adj[N+1]            // graph in adjacency vector list
int dfs(int current_vertex,int parent,int original_value,int other_value){
    int ans=0;
    vis[current_vertex]=1;                    // mark as visited  

    // map for adding values from neighbours having same value   
    map<int,int> mp;  
    // if curr vertex has value original_value then look for the neighbours  
    // having value as other,but if other is not defined define it   

    if(value[current_vertex]==original_value){   
        loop(i,adj[current_vertex].size()){
            int v=adj[current_vertex][i];
            if(v==parent)continue;
            if(!vis[v]){
                if(value[v]==other_value){
                   mp[value[v]]+=dfs(v,current_vertex,original,other);
                }
                else if(other==-1){  
                   mp[value[v]]+=dfs(v,current_vertex,original,value[v]);
                }
            }
        }
    }
   //else if the current_vertex has other value than look for original_value
    else{
        loop(i,adj[current_vertex].size()){
            int v=adj[current_vertex][i];
            if(v==p)continue;
            if(!vis[v]){
                if(value[v]==original){
                    mp[value[v]]+=dfs(v,current_vertex,original,other);
                }
            }
        }
    }    
    // find maximum length that can be found from neighbours of curr_vertex
    map<int,int> ::iterator ir=mp.begin();
    while(ir!=mp.end()){
        ans=max(ans,ir->second);
        ir++;
    }   
    return ans+1;
} 

致电:

// N is the number of vertices in original graph : n=|V|
for(int i=0;i<N;i++){  
    ans=max(ans,dfs(i,-1,value[i],-1);  
    memset(vis,0,sizeof(vis));  
}

但我希望改进此功能,以便在O(|V|+|E|)时间内运行。 |V|是veritces的数量,|E|是边数,我该怎么做?

1 个答案:

答案 0 :(得分:0)

这似乎并不难。遍历边缘列表并将每个边缘列表添加到由顶点标签规范对(图中的1,2,3,例如,对中第一个具有最低顶点标签值)键入的多图。

现在,对于multimap中的每个 - 这是一个边缘列表 - 累积相应的顶点集。

最大的顶点集对应于最大的二分图的边缘。

此算法遍历每个边两次,每边执行固定数量的映射和设置操作。因此,它的摊销运行时间和空间确实是O(| V | + | E |)。

请注意,使用邻接列表表示而不是矩阵实现此算法可能更简单,因为列表明确地给出了边缘。矩阵需要更仔细的遍历(如DFS)以避免Omega(| V | ^ 2)性能。