public class Drawing {
public HashMap<Integer, Node> nodes;
public HashSet<Edge> edges;
public Drawing() {
nodes = new HashMap<>();
edges = new HashSet<>();
}
public static class Node {
public int value;
public int in;
public int out;
public ArrayList<Node> nexts;
public ArrayList<Edge> edges;
public Node(int value) {
this.value = value;
in = 0;
out = 0;
nexts = new ArrayList<>();
edges = new ArrayList<>();
}
}
public static class Edge {
public int weight;
public Node from;
public Node to;
public Edge(int weight, Node from, Node to) {
this.weight = weight;
this.from = from;
this.to = to;
}
}
public static Drawing createGraph(Integer[][] matrix) {
Drawing graph = new Drawing();
for (int i = 0; i < matrix.length; i++) {
Integer from = matrix[i][0];
Integer to = matrix[i][1];
Integer weight = matrix[i][2];
if (!graph.nodes.containsKey(from)) {
graph.nodes.put(from, new Node(from));
}
if (!graph.nodes.containsKey(to)) {
graph.nodes.put(to, new Node(to));
}
Node fromNode = graph.nodes.get(from);
Node toNode = graph.nodes.get(to);
Edge newEdg = new Edge(weight, fromNode, toNode);
fromNode.nexts.add(toNode);
fromNode.out++;
toNode.in++;
fromNode.edges.add(newEdg);
graph.edges.add(newEdg);
}
return graph;
}
public static void bfs(Node node) {
if (node == null) {
return;
}
Queue<Node> queue = new LinkedList<Node>();
HashSet<Node> set = new HashSet<Node>();
queue.add(node);
set.add(node);
while (!queue.isEmpty()) {
Node cur = queue.poll();
System.out.println(cur.value);
for (Node next : cur.nexts) {
if (!set.contains(next)) {
set.add(next);
queue.add(next);
}
}
}
}
public static void dfs(Node node) {
if (node == null) {
return;
}
Stack<Node> stack = new Stack<>();
HashSet<Node> set = new HashSet<Node>();
stack.add(node);
set.add(node);
System.out.println(node.value);
while (!stack.isEmpty()) {
Node cur = stack.pop();
for (Node next : cur.nexts) {
if (!set.contains(next)) {
stack.push(cur);
stack.push(next);
set.add(next);
System.out.println(next.value);
break;
}
}
}
}
public static List<Node> sortedTopology(Drawing graph) {
HashMap<Node, Integer> inMap = new HashMap<>();
Queue<Node> zeroInQueue = new LinkedList<>();
for (Node node : graph.nodes.values()) {
inMap.put(node, node.in);
if (node.in == 0) {
zeroInQueue.add(node);
}
}
List<Node> result = new ArrayList<>();
while (!zeroInQueue.isEmpty()) {
Node cur = zeroInQueue.poll();
result.add(cur);
for (Node next : cur.nexts) {
inMap.put(next, inMap.get(next) - 1);
if (inMap.get(next) == 0) {
zeroInQueue.add(next);
}
}
}
return result;
}
public static class MySets {
public HashMap<Node, List<Node>> setMap = new HashMap<>();
public MySets(List<Node> nodes) {
for (Node cur : nodes) {
List<Node> set = new ArrayList<>();
set.add(cur);
setMap.put(cur, set);
}
}
public boolean isSameSet(Node from, Node to) {
List<Node> fromSet = setMap.get(from);
List<Node> toSet = setMap.get(to);
return fromSet == toSet;
}
public void union(Node from, Node to) {
List<Node> fromSet = setMap.get(from);
List<Node> toSet = setMap.get(to);
for (Node toNode : toSet) {
fromSet.add(toNode);
setMap.put(toNode, fromSet);
}
}
public static Set<Edge> kruskaLMST(Drawing graph) {
HashMap<Integer, Node> nodes = graph.nodes;
Collection<Node> values = nodes.values();
List<Node> collect = values.stream().collect(Collectors.toList());
MySets set = new MySets(collect);
PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new Comparequeue());
HashSet<Edge> edges = graph.edges;
for (Edge edge : edges) {
priorityQueue.add(edge);
}
Set<Edge> result = new HashSet<>();
while (!priorityQueue.isEmpty()) {
Edge edge = priorityQueue.poll();
boolean sameSet = set.isSameSet(edge.from, edge.to);
if (!sameSet) {
result.add(edge);
set.union(edge.from, edge.to);
}
}
return result;
}
public static class Comparequeue implements Comparator<Edge> {
@Override
public int compare(Edge o1, Edge o2) {
return o1.weight - o2.weight;
}
}
}
public static Set<Edge> primMST(Drawing graph) {
PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new MySets.Comparequeue());
HashSet<Node> set = new HashSet<>();
Set<Edge> result = new HashSet<>();
for (Node node : graph.nodes.values()) {
if (!set.contains(node)) {
set.add(node);
for (Edge edge : node.edges) {
priorityQueue.add(edge);
}
while (!priorityQueue.isEmpty()) {
Edge edge = priorityQueue.poll();
Node toNode = edge.to;
if (!set.contains(toNode)) {
set.add(toNode);
result.add(edge);
for (Edge nextEdge : toNode.edges) {
priorityQueue.add(nextEdge);
}
}
}
}
}
return result;
}
public static void main(String[] args) {
Drawing tu = new Drawing();
HashMap<Integer, Node> nodes = new HashMap<>();
HashSet<Edge> edges = new HashSet<>();
Node n1 = new Node(1);
Node n2 = new Node(2);
Node n3 = new Node(3);
Node n4 = new Node(4);
Node n5 = new Node(5);
n1.nexts.add(n2);
n1.nexts.add(n4);
n1.nexts.add(n3);
n2.nexts.add(n1);
n2.nexts.add(n3);
n3.nexts.add(n1);
n3.nexts.add(n2);
n3.nexts.add(n4);
n3.nexts.add(n5);
n4.nexts.add(n1);
n4.nexts.add(n3);
n1.in = 3;
n2.in = 2;
n3.in = 4;
n4.in = 2;
n5.in = 1;
n1.out = 3;
n2.out = 2;
n3.out = 4;
n5.out = 1;
nodes.put(1, n1);
nodes.put(2, n2);
nodes.put(3, n3);
nodes.put(4, n4);
nodes.put(5, n5);
tu.nodes = nodes;
Edge edge1 = new Edge(20, n1, n4);
Edge edge2 = new Edge(1000, n1, n3);
Edge edge3 = new Edge(30, n1, n2);
Edge edge4 = new Edge(10, n2, n3);
Edge edge5 = new Edge(20, n3, n5);
edges.add(edge1);
edges.add(edge2);
edges.add(edge3);
edges.add(edge4);
edges.add(edge5);
tu.edges = edges;
MySets.kruskaLMST(tu);
}
}