在图中查找良好反馈边集的Java程序
反馈边集是有向图 G 的一组边,其中 F ⊆ E,其每个循环必须至少包含来自 F 的一条边。
简单来说,反馈边集是从图中去除的边的集合,使得图成为有向无环图。
例子:
Input:
Output:
Feedback Edge Set: ( 3 -> 1 ) ( 4 -> 3 )
Explanation:
Clearly two edges 3 -> 1 and 4 -> 3 will make the graph acyclic.
方法:
可以使用简单的 BFS 找出反馈边集,但如果给定的图是 DAG,则必须没有边集。
- 检查给定的图是否已经是有向无环图并删除所有汇顶点。
- 返回修改后的图形并运行 BFS。
- 在运行 BFS 时标记访问过的顶点。
- 如果再次访问标记的顶点,则将该边打印为反馈边。
代码:
Java
// Java Program to find a good feedback
// edge set in a graph
import java.util.*;
class Graph
{
// Map for storing graph in adj list
private Map> adjacencyList;
// Graph Constructor
public Graph(int v)
{
// Create adj List
adjacencyList = new HashMap>();
// Create empty adj list for each vertex
for (int i = 1; i <= v; i++)
{
adjacencyList.put(i, new LinkedList());
}
}
// Adding new edge
public void setEdge(int src, int dest)
{
List neighbours = adjacencyList.get(src);
neighbours.add(dest);
}
// Function for checking DAG
// and removing sink vertex
public Graph checkAcyclic()
{
Integer count = 0;
// Iterator for all the vertices
Iterator nodes = this.adjacencyList.keySet().iterator();
Integer size = this.adjacencyList.size() - 1;
// Traverse till the last node
while (nodes.hasNext())
{
Integer i = nodes.next();
// Get the neighbours of the selected vertex
List adjList = this.adjacencyList.get(i);
// If the given graph is DAG
if (count == size)
{
return this;
}
// If it's a sink vertex
if (adjList.size() == 0)
{
count++;
Iterator neighbour
= this.adjacencyList.keySet().iterator();
// Remove all edges from that vertex
while (neighbour.hasNext())
{
Integer j = neighbour.next();
List egdes = this.adjacencyList.get(j);
if (egdes.contains(i))
{
egdes.remove(i);
}
}
// Remove the vertex from the graph
this.adjacencyList.remove(i);
nodes = this.adjacencyList.keySet().iterator();
}
}
// Return the modified graph
return this;
}
// Function to find the
// feedback edge set
public boolean getFeedbackEdgeSet()
{
int v=this.adjacencyList.size();
boolean flag = false;
// Array to mark the visited vertices
int[] visited = new int[v + 1];
// Iterator for all the vertices
Iterator nodes
= this.adjacencyList.keySet().iterator();
// Traverse till the last node
while (nodes.hasNext())
{
Integer i = nodes.next();
// Get the neighbours of the vertex
List neighbours = this.adjacencyList.get(i);
visited[i] = 1;
if (neighbours.size() != 0)
{
for (int j = 0; j < neighbours.size(); j++)
{
// If the vertex is already visited
if (visited[neighbours.get(j)] == 1)
{
// Mark flag to true denoting
// the given graph is not DAG
flag = true;
System.out.print("( "+i+" -> "+
neighbours.get(j)+" ) ");
}
// Mark if not visited yet
else
{
visited[neighbours.get(j)] = 1;
}
}
}
}
return flag;
}
}
// Driver Code
public class GFG
{
public static void main(String args[])
{
// Number of vertices and edges
int v = 4;
int e = 5;
// Initialize new Graph
Graph g = new Graph(v);
// Edges
g.setEdge(1,2);
g.setEdge(2,3);
g.setEdge(4,3);
g.setEdge(1,4);
g.setEdge(3,1);
// Run the function
g = g.checkAcyclic();
System.out.print("Feedback Edge Set: ");
if (g.getFeedbackEdgeSet() == false)
{
System.out.println("None");
}
}
}
输出
Feedback Edge Set: ( 3 -> 1 ) ( 4 -> 3 )
时间复杂度: O(E*V),其中 E 是边数,V 是顶点数。