-1

Given an undirected unweighted graph : it may be cyclic and each vertex has given value ,as shown in image.

Original Graph

Find the size of largest Bi-Partite sub-graph (Largest means maximum number of vertices (connected) in that graph) ?

Answer:

The solution is shown here

The largest graph is the orange-coloured one, so the answer is 8.

My approach:

#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;
} 

calling :

// 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));  
}

But I'd like to improve this to run in O(|V|+|E|) time. |V| is the number of veritces and |E| is the number of edges and How do I do that?

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
  • Welcome to stack overflow. Please read the help on how to ask a question, especially regarding [minimum, complete, verifiable examples](https://stackoverflow.com/help/mcve). You haven't even explained your graph representation. It's asking a lot to improve an algorithm given as messy C++. At any rate, I doubt you'll find a correct algorithm that doesn't touch all edges in some manner. No O(|V|) algorithm can do that. – Gene Jun 07 '18 at 05:38
  • I have done editing now – tatya bichu Jun 07 '18 at 06:31

1 Answers1

0

This doesn't seem hard. Traverse the edge list and add each one to a multimap keyed by vertex label canonical pairs (the 1,2,3 in your diagram, e.g. with the lowest vertex label value first in the pair).

Now for each value in the multimap - which is a list of edges - accumulate the corresponding vertex set.

The biggest vertex set corresponds to the edges of the biggest bipartite graph.

This algorithm traverses each edge twice, doing a fixed number of map and set operations per edge. So its amortized run time and space is indeed O(|V|+|E|).

Note that it's probably simpler to implement this algorithm with an adjacency list representation than with a matrix because the list gives the edge explicitly. The matrix requires a more careful traversal (like a DFS) to avoid Omega(|V|^2) performance.

Gene
  • 46,253
  • 4
  • 58
  • 96