http://www.geeksforgeeks.org/maximum-edges-can-added-dag-remains-dag/
A DAG is given to us, we need to find maximum number of edges that can be added to this DAG, after which new graph still remain a DAG that means the reformed graph should have maximal number of edges, adding even single edge will create a cycle in graph.
The Output for above example should be following edges in any order. 4-2, 4-5, 4-3, 5-3, 5-1, 2-0, 2-1, 0-3, 0-1
we have added all the edges in one direction only to save ourselves from making a cycle. This is the trick to solve this question. We sort all our nodes in topological order and create edges from node to all nodes to the right if not there already.
How can we say that, it is not possible to add any more edge? the reason is we have added all possible edges from left to right and if we want to add more edge we need to make that from right to left, but adding edge from right to left we surely create a cycle because its counter part left to right edge is already been added to graph and creating cycle is not what we needed.
So solution proceeds as follows, we consider the nodes in topological order and if any edge is not there from left to right, we will create it.
How can we say that, it is not possible to add any more edge? the reason is we have added all possible edges from left to right and if we want to add more edge we need to make that from right to left, but adding edge from right to left we surely create a cycle because its counter part left to right edge is already been added to graph and creating cycle is not what we needed.
So solution proceeds as follows, we consider the nodes in topological order and if any edge is not there from left to right, we will create it.
class
Graph
{
int
V;
// No. of vertices
// Pointer to a list containing adjacency list
list<
int
> *adj;
// Vector to store indegree of vertices
vector<
int
> indegree;
// function returns a topological sort
vector<
int
> topologicalSort();
public
:
Graph(
int
V);
// Constructor
// function to add an edge to graph
void
addEdge(
int
v,
int
w);
// Prints all edges that can be added without making any cycle
void
maximumEdgeAddtion();
};
// Constructor of graph
Graph::Graph(
int
V)
{
this
->V = V;
adj =
new
list<
int
>[V];
// Initialising all indegree with 0
for
(
int
i = 0; i < V; i++)
indegree.push_back(0);
}
// Utility function to add edge
void
Graph::addEdge(
int
v,
int
w)
{
adj[v].push_back(w);
// Add w to v's list.
// increasing inner degree of w by 1
indegree[w]++;
}
// Main function to print maximum edges that can be added
vector<
int
> Graph::topologicalSort()
{
vector<
int
> topological;
queue<
int
> q;
// In starting push all node with indegree 0
for
(
int
i = 0; i < V; i++)
if
(indegree[i] == 0)
q.push(i);
while
(!q.empty())
{
int
t = q.front();
q.pop();
// push the node into topological vector
topological.push_back(t);
// reducing indegree of adjacent vertices
for
(list<
int
>:: iterator j = adj[t].begin();
j != adj[t].end(); j++)
{
indegree[*j]--;
// if indegree becomes 0, just push
// into queue
if
(indegree[*j] == 0)
q.push(*j);
}
}
return
topological;
}
// The function prints all edges that can be
// added without making any cycle
// It uses recursive topologicalSort()
void
Graph::maximumEdgeAddtion()
{
bool
*visited =
new
bool
[V];
vector<
int
> topo = topologicalSort();
// looping for all nodes
for
(
int
i = 0; i < topo.size(); i++)
{
int
t = topo[i];
// In below loop we mark the adjacent node of t
for
(list<
int
>::iterator j = adj[t].begin();
j != adj[t].end(); j++)
visited[*j] =
true
;
// In below loop unmarked nodes are printed
for
(
int
j = i + 1; j < topo.size(); j++)
{
// if not marked, then we can make an edge
// between t and j
if
(!visited[topo[j]])
cout << t <<
"-"
<< topo[j] <<
" "
;
visited[topo[j]] =
false
;
}
}
}