【问题标题】:How to find largest bi-partite subgraph in the given graph?如何在给定图中找到最大的二分子图?
【发布时间】:2018-06-07 05:20:36
【问题描述】:

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

找到最大的 Bi-Partite 子图的大小(最大意味着该图中的最大顶点数(连接))?

答案:

最大的图表是橙色的,所以答案是 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| 是顶点数,|E| 是边数,我该怎么做?

【问题讨论】:

  • 欢迎堆栈溢出。请阅读有关如何提问的帮助,尤其是关于 minimum, complete, verifiable examples 的帮助。你甚至没有解释你的图形表示。改进作为杂乱 C++ 给出的算法需要很多。无论如何,我怀疑你会找到一个不会以某种方式触及所有边缘的正确算法。没有 O(|V|) 算法可以做到这一点。
  • 我已经完成了编辑

标签: c++ graph depth-first-search bipartite subgraph


【解决方案1】:

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

现在对于多重映射中的每个 - 这是一个边列表 - 累积相应的顶点集。

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

该算法遍历每条边两次,对每条边执行固定数量的映射和集合操作。所以它的摊销运行时间和空间确实是 O(|V|+|E|)。

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

【讨论】:

    猜你喜欢
    • 2012-09-09
    • 1970-01-01
    • 2015-01-09
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    • 2011-03-10
    • 2011-10-04
    • 1970-01-01
    相关资源
    最近更新 更多