Add code
This commit is contained in:
parent
6fef06fdef
commit
fc5aee5646
83
Couple.java
Normal file
83
Couple.java
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2009 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Container to ease passing around a tuple of two objects. This object provides a sensible
|
||||
* implementation of equals(), returning true if equals() is true on each of the contained
|
||||
* objects.
|
||||
*
|
||||
* @link https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/util/Pair.java
|
||||
*/
|
||||
public class Couple<F, S> {
|
||||
public final F first;
|
||||
public final S second;
|
||||
|
||||
/**
|
||||
* Constructor for a Couple.
|
||||
*
|
||||
* @param first the first object in the Couple
|
||||
* @param second the second object in the Couple
|
||||
*/
|
||||
public Couple(F first, S second) {
|
||||
this.first = first;
|
||||
this.second = second;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the two objects for equality by delegating to their respective
|
||||
* {@link Object#equals(Object)} methods.
|
||||
*
|
||||
* @param o the {@link Couple} to which this one is to be checked for equality
|
||||
* @return true if the underlying objects of the Couple are both considered
|
||||
* equal
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Couple)) {
|
||||
return false;
|
||||
}
|
||||
Couple<?, ?> p = (Couple<?, ?>) o;
|
||||
return Objects.equals(p.first, first) && Objects.equals(p.second, second);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute a hash code using the hash codes of the underlying objects
|
||||
*
|
||||
* @return a hashcode of the Couple
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (first == null ? 0 : first.hashCode()) ^ (second == null ? 0 : second.hashCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Couple{" + String.valueOf(first) + " " + String.valueOf(second) + "}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method for creating an appropriately typed couple.
|
||||
*
|
||||
* @param a the first object in the Couple
|
||||
* @param b the second object in the Couple
|
||||
* @return a Couple that is templatized with the types of a and b
|
||||
*/
|
||||
public static <A, B> Couple<A, B> create(A a, B b) {
|
||||
return new Couple<A, B>(a, b);
|
||||
}
|
||||
}
|
129
DFS.java
Normal file
129
DFS.java
Normal file
@ -0,0 +1,129 @@
|
||||
package CompetitiveProgramming.Uva;
|
||||
|
||||
import CompetitiveProgramming.DirectedMultiGraph;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class
|
||||
M11709
|
||||
{
|
||||
static DirectedMultiGraph g, g_transpose;
|
||||
static int n_nodes, // P
|
||||
T,
|
||||
idx;
|
||||
static Map<String, Integer> name_idx;
|
||||
private static int number_of_scc = 0,
|
||||
current_scc_n_nodes = 0;
|
||||
|
||||
/**
|
||||
* WARNING: Changes all graph nodes' visited state to true
|
||||
* temporary storage: current_scc_n_nodes won't be reset by the end
|
||||
*
|
||||
* Time complexity: O(E+N)
|
||||
* void operations: Will set number_of_scc
|
||||
*
|
||||
* @param g DirectedMultiGraph The graph to be used
|
||||
* @param u int The start point
|
||||
* @param dfs_finished_stack Stack<int> ending_sequence I/O (optional) If DAG is given,
|
||||
* it will correspond to a top sort (total order)
|
||||
*/
|
||||
@SafeVarargs
|
||||
private static void
|
||||
dfs_visit(DirectedMultiGraph g, int u, ArrayDeque<Integer>... dfs_finished_stack) {
|
||||
g.seen[u] = true;
|
||||
++current_scc_n_nodes;
|
||||
|
||||
for (int w : g.edges(u)) {
|
||||
if (!g.seen[w]) {
|
||||
dfs_visit(g, w, dfs_finished_stack);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if a dfs_finished_stack was supplied to be filled
|
||||
if (dfs_finished_stack.length == 1) {
|
||||
dfs_finished_stack[0].addFirst(u);
|
||||
}
|
||||
}
|
||||
|
||||
// Time complexity: O(E+N)
|
||||
private static void
|
||||
kosaraju_sharir(DirectedMultiGraph g, DirectedMultiGraph g_transpose, int n_nodes) {
|
||||
// DFS visit the graph
|
||||
ArrayDeque<Integer> dfs_finished_stack = new ArrayDeque<>();
|
||||
for (int v = 0; v < n_nodes; ++v) {
|
||||
if (!g.seen[v]) {
|
||||
dfs_visit(g, v, dfs_finished_stack);
|
||||
}
|
||||
}
|
||||
|
||||
// Reset globals
|
||||
current_scc_n_nodes = 0;
|
||||
number_of_scc = 0;
|
||||
|
||||
// DFS visit in transposed graph using dfs_finished_stack seq
|
||||
while (!dfs_finished_stack.isEmpty()) {
|
||||
int v = dfs_finished_stack.removeFirst();
|
||||
|
||||
// New component is being discovered
|
||||
if (!g_transpose.seen[v]) {
|
||||
current_scc_n_nodes = 0;
|
||||
dfs_visit(g_transpose, v);
|
||||
|
||||
// Actions
|
||||
++number_of_scc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int
|
||||
idx_in_graph(String name) {
|
||||
Integer u = name_idx.get(name);
|
||||
if (u == null) {
|
||||
u = idx++;
|
||||
name_idx.put(name, u);
|
||||
}
|
||||
return u;
|
||||
}
|
||||
|
||||
public static boolean
|
||||
generate_structures(Scanner stdin) {
|
||||
if (n_nodes == 0 && T == 0) return false;
|
||||
stdin.nextLine(); // flush from int buffer
|
||||
name_idx = new HashMap<>(n_nodes);
|
||||
idx = 0;
|
||||
g = new DirectedMultiGraph(n_nodes, true);
|
||||
g_transpose = new DirectedMultiGraph(n_nodes, true);
|
||||
|
||||
for (int p = 0; p < n_nodes; ++p) {
|
||||
String name = stdin.nextLine();
|
||||
idx_in_graph(name);
|
||||
}
|
||||
for (int t = 0; t < T; ++t) {
|
||||
String u_name = stdin.nextLine(),
|
||||
w_name = stdin.nextLine();
|
||||
int u = idx_in_graph(u_name),
|
||||
w = idx_in_graph(w_name);
|
||||
g.link_first(u, w);
|
||||
g_transpose.link_first(w, u);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void
|
||||
main(String[] args) {
|
||||
// Input and Data Representation
|
||||
Scanner stdin = new Scanner(System.in);
|
||||
while (true) {
|
||||
n_nodes = stdin.nextInt();
|
||||
T = stdin.nextInt();
|
||||
if (!generate_structures(stdin)) break;
|
||||
// Process
|
||||
kosaraju_sharir(g, g_transpose, n_nodes);
|
||||
// Output
|
||||
System.out.println(number_of_scc);
|
||||
}
|
||||
// That's all folks
|
||||
stdin.close();
|
||||
}
|
||||
}
|
85
DirectedMultiGraph.java
Normal file
85
DirectedMultiGraph.java
Normal file
@ -0,0 +1,85 @@
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* The DirectedMultiGraph class is a structure to store a non-weighted
|
||||
* graph of nodes named 0 through N-1.
|
||||
* The implementation uses an adjacency-lists representation.
|
||||
* @author Diogo Peralta Cordeiro <diogo@fc.up.pt>
|
||||
*/
|
||||
public class
|
||||
DirectedMultiGraph
|
||||
{
|
||||
private final List<LinkedList<Integer>> edges;
|
||||
public final int[] out_degree, in_degree;
|
||||
public int n_nodes, n_edges; // N, #Edges, respectively
|
||||
|
||||
// O(n) to construct the structure
|
||||
public
|
||||
DirectedMultiGraph (int n_nodes)
|
||||
{
|
||||
this.n_nodes = n_nodes;
|
||||
this.n_edges = 0;
|
||||
this.edges = new ArrayList<>(n_nodes);
|
||||
this.out_degree = new int[n_nodes];
|
||||
this.in_degree = new int[n_nodes];
|
||||
for (int i = 0; i < n_nodes; ++i)
|
||||
{
|
||||
this.edges.add(i, new LinkedList<>());
|
||||
}
|
||||
}
|
||||
|
||||
// O(1) to get the adjacency-list for a node
|
||||
public LinkedList<Integer>
|
||||
edges (int u)
|
||||
{
|
||||
return this.edges.get(u);
|
||||
}
|
||||
|
||||
// O(1) to get the first adjacency of a node
|
||||
public int
|
||||
first_edge (int u)
|
||||
{
|
||||
return this.edges.get(u).getFirst();
|
||||
}
|
||||
|
||||
// O(1) to add an adjacency
|
||||
public final void
|
||||
link_first (int u, int w)
|
||||
{
|
||||
// If we don't want a Multi-graph and can't avoid
|
||||
// duplicate links from the outside, uncomment the following
|
||||
// line
|
||||
//if (node_links(u).contains(w)) return;
|
||||
this.edges(u).addFirst(w);
|
||||
++this.out_degree[u];
|
||||
++this.in_degree[w];
|
||||
++this.n_edges;
|
||||
}
|
||||
|
||||
// O(1) to remove an adjacency
|
||||
public void
|
||||
unlink_first (int u)
|
||||
{
|
||||
try
|
||||
{
|
||||
int w = this.edges(u).removeFirst();
|
||||
--this.out_degree[u];
|
||||
--this.in_degree[w];
|
||||
--this.n_edges;
|
||||
}
|
||||
catch (NoSuchElementException e)
|
||||
{
|
||||
// void.
|
||||
}
|
||||
}
|
||||
|
||||
// Convenience: In case the requester needs to hold such type of information about the nodes
|
||||
public boolean[] seen;
|
||||
public
|
||||
DirectedMultiGraph (int n_nodes, boolean have_seen)
|
||||
{
|
||||
this(n_nodes);
|
||||
if (have_seen)
|
||||
seen = new boolean[n_nodes];
|
||||
}
|
||||
}
|
275
DirectedWeightedGraph.java
Normal file
275
DirectedWeightedGraph.java
Normal file
@ -0,0 +1,275 @@
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* The DirectedWeightedGraph class is a structure to store a n-weighted
|
||||
* graph of nodes named 0 through N-1.
|
||||
* The implementation uses an adjacency-lists representation for the graph
|
||||
* and a HashMap indexed by strings of the form "u-v", u and v being nodes,
|
||||
* the map's values are a List of generic type.
|
||||
* Each edge can have a different number of weights (or even none).
|
||||
* @author Diogo Peralta Cordeiro <diogo@fc.up.pt>
|
||||
*/
|
||||
public class
|
||||
DirectedWeightedGraph<T>
|
||||
{
|
||||
private final List<LinkedList<Integer>> edges;
|
||||
private final Map<String, List<T>> edges_weights;
|
||||
public int n_nodes, n_edges; // N, #Edges, respectively
|
||||
|
||||
// O(n) to construct the structure
|
||||
public
|
||||
DirectedWeightedGraph (int n_nodes)
|
||||
{
|
||||
this.n_nodes = n_nodes;
|
||||
this.n_edges = 0;
|
||||
this.edges = new ArrayList<>(n_nodes);
|
||||
this.edges_weights = new HashMap<>(n_nodes);
|
||||
for (int i = 0; i < n_nodes; ++i)
|
||||
{
|
||||
this.edges.add(i, new LinkedList<>());
|
||||
}
|
||||
}
|
||||
|
||||
// O(1) to get the adjacency-list for a node
|
||||
public LinkedList<Integer>
|
||||
edges (int u)
|
||||
{
|
||||
return this.edges.get(u);
|
||||
}
|
||||
|
||||
// O(1) to get the weights list
|
||||
public List<T>
|
||||
weight (int u, int w)
|
||||
{
|
||||
return this.edges_weights.get(u + "-" + w);
|
||||
}
|
||||
|
||||
// O(1) to add a node to the last position of the adjacency-list
|
||||
// O(1) to update the weight of an existing edge
|
||||
@SafeVarargs
|
||||
public final void
|
||||
link (int u, int w, T... weight)
|
||||
{
|
||||
// O(1) to ensure we don't make a MultiGraph
|
||||
if (!this.edges(u).contains(w)) {
|
||||
// O(1) to add an adjacency
|
||||
this.edges(u).addLast(w);
|
||||
|
||||
++this.n_edges;
|
||||
}
|
||||
|
||||
// O(1) to put or update a weight, if we want to
|
||||
this.edges_weights.put(u + "-" + w, Arrays.asList(weight));
|
||||
}
|
||||
|
||||
// O(n) to remove a node
|
||||
public void
|
||||
delete_node (int u)
|
||||
{
|
||||
for (int w = 0; w < this.n_nodes; ++w)
|
||||
{
|
||||
this.unlink(u, w);
|
||||
this.unlink(w, u);
|
||||
}
|
||||
}
|
||||
|
||||
// O(n) to remove an adjacency
|
||||
public void
|
||||
unlink (int u, int w)
|
||||
{
|
||||
// O(n)
|
||||
this.edges(u).remove((Integer) w);
|
||||
|
||||
// O(1)
|
||||
this.edges_weights.remove(u + "-" + w);
|
||||
|
||||
--this.n_edges;
|
||||
}
|
||||
|
||||
/* UTILS */
|
||||
|
||||
// O(#Edges + N*lg(N))
|
||||
public List<Object>
|
||||
int_dijkstra(int s) {
|
||||
/* Set Data Structures */
|
||||
int[] dist = new int[this.n_nodes];
|
||||
List<List<Integer>> come_from = new ArrayList<>(this.n_nodes);
|
||||
for (int i = 0; i < this.n_nodes; ++i) {
|
||||
dist[i] = 1000000000; // 1e9 to avoid overflow
|
||||
come_from.add(i, new LinkedList<>());
|
||||
}
|
||||
// Compare by distance, then by index
|
||||
TreeSet<Integer> to_explore = new TreeSet<>(Comparator.comparingInt((Integer i) -> dist[i]).thenComparingInt(i -> i));
|
||||
|
||||
// Let's find distances from s
|
||||
dist[s] = 0;
|
||||
to_explore.add(s);
|
||||
|
||||
// Dijkstra's Algorithm
|
||||
while (!to_explore.isEmpty()) {
|
||||
int u = to_explore.pollFirst();
|
||||
// Assert: u.distance is the true shortest distance from s to u
|
||||
// Assert: u is never put back into to_explore
|
||||
this.edges(u).forEach((w) -> {
|
||||
int edge_cost = (int) this.weight(u, w).get(0);
|
||||
int dist_w = dist[u] + edge_cost;
|
||||
if (dist_w < dist[w]) {
|
||||
come_from.get(w).clear();
|
||||
come_from.get(w).add(u);
|
||||
// Decrease key with new distance
|
||||
to_explore.remove(w);
|
||||
dist[w] = dist_w;
|
||||
to_explore.add(w);
|
||||
} else if (dist_w == dist[w]) {
|
||||
come_from.get(w).add(u);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// That's all folks.
|
||||
return Arrays.asList(dist, come_from);
|
||||
}
|
||||
public List<Object>
|
||||
double_dijkstra(int s) {
|
||||
/* Set Data Structures */
|
||||
double[] dist = new double[this.n_nodes];
|
||||
List<List<Integer>> come_from = new ArrayList<>(this.n_nodes);
|
||||
for (int i = 0; i < this.n_nodes; ++i) {
|
||||
dist[i] = 1000000000; // 1e9 to avoid overflow
|
||||
come_from.add(i, new LinkedList<>());
|
||||
}
|
||||
// Compare by distance, then by index
|
||||
TreeSet<Integer> to_explore = new TreeSet<>(Comparator.comparingDouble((Integer i) -> dist[i]).thenComparingInt(i -> i));
|
||||
|
||||
// Let's find distances from s
|
||||
dist[s] = 0;
|
||||
to_explore.add(s);
|
||||
|
||||
// Dijkstra's Algorithm
|
||||
while (!to_explore.isEmpty()) {
|
||||
int u = to_explore.pollFirst();
|
||||
// Assert: u.distance is the true shortest distance from s to u
|
||||
// Assert: u is never put back into to_explore
|
||||
this.edges(u).forEach((w) -> {
|
||||
double edge_cost = (double) this.weight(u, w).get(0);
|
||||
double dist_w = dist[u] + edge_cost;
|
||||
if (Double.compare(dist_w, dist[w]) < 0) {
|
||||
come_from.get(w).clear();
|
||||
come_from.get(w).add(u);
|
||||
// Decrease key with new distance
|
||||
to_explore.remove(w);
|
||||
dist[w] = dist_w;
|
||||
to_explore.add(w);
|
||||
} else if (Double.compare(dist_w, dist[w]) == 0) {
|
||||
come_from.get(w).add(u);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// That's all folks.
|
||||
return Arrays.asList(dist, come_from);
|
||||
}
|
||||
|
||||
// O(#Edges + N*lg(N))
|
||||
public int[]
|
||||
int_prim() {
|
||||
/* Set Data Structures */
|
||||
int[] dist = new int[this.n_nodes];
|
||||
boolean[] in_tree = new boolean[this.n_nodes];
|
||||
int[] come_from = new int[this.n_nodes];
|
||||
Arrays.fill(dist, 1000000000); // 1e9 to avoid overflow
|
||||
TreeSet<Integer> to_explore = new TreeSet<>(Comparator.comparingInt((Integer i) -> dist[i]).thenComparingInt(i -> i));
|
||||
|
||||
// Let's find distances from s
|
||||
int s = 0;
|
||||
dist[s] = 0;
|
||||
to_explore.add(s);
|
||||
|
||||
while (!to_explore.isEmpty()) {
|
||||
int u = to_explore.pollFirst();
|
||||
in_tree[u] = true;
|
||||
// Let t be the graph made of nodes with in_tree = true,
|
||||
// and edges {(w - come_from[w]), for w in g.nodes excluding s}
|
||||
// Assert: t is part of an MST for g
|
||||
this.edges(u).forEach((w) -> {
|
||||
int edge_cost = (int) this.weight(u, w).get(0);
|
||||
if (!in_tree[w] && edge_cost < dist[w]) {
|
||||
come_from[w] = u;
|
||||
to_explore.remove(w);
|
||||
dist[w] = edge_cost;
|
||||
to_explore.add(w);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// That's all folks.
|
||||
return come_from;
|
||||
}
|
||||
public int[]
|
||||
double_prim() {
|
||||
/* Set Data Structures */
|
||||
double[] dist = new double[this.n_nodes];
|
||||
boolean[] in_tree = new boolean[this.n_nodes];
|
||||
int[] come_from = new int[this.n_nodes];
|
||||
Arrays.fill(dist, 1000000000); // 1e9 to avoid overflow
|
||||
TreeSet<Integer> to_explore = new TreeSet<>(Comparator.comparingDouble((Integer i) -> dist[i]).thenComparingInt(i -> i));
|
||||
|
||||
// Let's find distances from s
|
||||
int s = 0;
|
||||
dist[s] = 0;
|
||||
to_explore.add(s);
|
||||
|
||||
while (!to_explore.isEmpty()) {
|
||||
int u = to_explore.pollFirst();
|
||||
in_tree[u] = true;
|
||||
// Let t be the graph made of nodes with in_tree = true,
|
||||
// and edges {(w - come_from[w]), for w in g.nodes excluding s}
|
||||
// Assert: t is part of an MST for g
|
||||
this.edges(u).forEach((w) -> {
|
||||
double edge_cost = (double) this.weight(u, w).get(0);
|
||||
if (!in_tree[w] && Double.compare(edge_cost, dist[w]) < 0) {
|
||||
come_from[w] = u;
|
||||
to_explore.remove(w);
|
||||
dist[w] = edge_cost;
|
||||
to_explore.add(w);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// That's all folks.
|
||||
return come_from;
|
||||
}
|
||||
|
||||
// O(N*#Edges)
|
||||
public int[]
|
||||
int_bellman_ford (int s) throws Exception {
|
||||
int[] min_weight = new int[this.n_nodes];
|
||||
// best estimate so far of minimum weight from s to another vertex
|
||||
Arrays.fill(min_weight, 1000000000); // 1e9 to avoid overflow
|
||||
min_weight[s] = 0;
|
||||
|
||||
// Repeat
|
||||
for (int i = 0; i < this.n_nodes; ++i) {
|
||||
// relax all the edges
|
||||
for (int u = 0; u < this.n_nodes; ++u) {
|
||||
for (int w : this.edges(u)) {
|
||||
int edge_cost = (int) this.weight(u, w).get(0);
|
||||
min_weight[w] = Math.min(min_weight[u] + edge_cost, min_weight[w]);
|
||||
// Assert: v.min_weight >= true minimum weight from s to v
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int u = 0; u < this.n_nodes; ++u) {
|
||||
for (int w : this.edges(u)) {
|
||||
int edge_cost = (int) this.weight(u, w).get(0);
|
||||
if (min_weight[u] + edge_cost < min_weight[w]) {
|
||||
throw new Exception("Negative-weight cycle detected.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// That's all folks.
|
||||
return min_weight;
|
||||
}
|
||||
}
|
10
FastPrint.java
Normal file
10
FastPrint.java
Normal file
@ -0,0 +1,10 @@
|
||||
package ProgrammingChallenges;
|
||||
// FastPrint (remember to call FastPrint.out.close() at the end)
|
||||
// Pedro Ribeiro (DCC/FCUP)
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class FastPrint {
|
||||
public static PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
|
||||
}
|
61
FastScanner.java
Normal file
61
FastScanner.java
Normal file
@ -0,0 +1,61 @@
|
||||
package ProgrammingChallenges;
|
||||
// FastScanner
|
||||
// Pedro Ribeiro (DCC/FCUP)
|
||||
// Minor edits by Diogo Cordeiro
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
public class FastScanner {
|
||||
BufferedReader br;
|
||||
StringTokenizer st;
|
||||
|
||||
public FastScanner(InputStream stream) {
|
||||
br = new BufferedReader(new InputStreamReader(stream));
|
||||
}
|
||||
|
||||
public String next() {
|
||||
while (st == null || !st.hasMoreElements()) {
|
||||
String ffs = null;
|
||||
try {
|
||||
ffs = br.readLine();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (ffs != null)
|
||||
st = new StringTokenizer(ffs);
|
||||
else return null;
|
||||
}
|
||||
return st.nextToken();
|
||||
}
|
||||
|
||||
//public Integer nextInt() {
|
||||
public int nextInt() {
|
||||
//String n = next();
|
||||
//if (n == null) return null;
|
||||
//return Integer.parseInt(n);
|
||||
return Integer.parseInt(next());
|
||||
}
|
||||
|
||||
public long nextLong() {
|
||||
return Long.parseLong(next());
|
||||
}
|
||||
|
||||
public double nextDouble() {
|
||||
return Double.parseDouble(next());
|
||||
}
|
||||
|
||||
public String nextLine() {
|
||||
String str = "";
|
||||
try {
|
||||
str = br.readLine();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
}
|
90
FloydWarshall.java
Normal file
90
FloydWarshall.java
Normal file
@ -0,0 +1,90 @@
|
||||
/* Input */
|
||||
// Information about the group
|
||||
int n_elements = stdin.nextInt(),
|
||||
start = stdin.nextInt(),
|
||||
budget = stdin.nextInt(),
|
||||
// Information about the network
|
||||
n_nodes = stdin.nextInt(),
|
||||
n_edges = stdin.nextInt(),
|
||||
NO_EDGE = 1000000000; // 1e9 to avoid overflow
|
||||
// Graph as a adjacency-matrix
|
||||
int[][] adj = new int[n_nodes][n_nodes];
|
||||
for (int i = 0; i < n_nodes; ++i)
|
||||
{
|
||||
Arrays.fill(adj[i], NO_EDGE);
|
||||
adj[i][i] = 0;
|
||||
}
|
||||
for (int i = 0; i < n_edges; ++i)
|
||||
{
|
||||
int source = stdin.nextInt()-1,
|
||||
dest = stdin.nextInt()-1,
|
||||
spots = stdin.nextInt(),
|
||||
cost = stdin.nextInt();
|
||||
|
||||
if (spots >= n_elements
|
||||
&& cost <= budget) // prevents stupidly expensive edges
|
||||
{
|
||||
adj[source][dest] = cost;
|
||||
}
|
||||
else
|
||||
{
|
||||
adj[source][dest] = NO_EDGE;
|
||||
}
|
||||
}
|
||||
|
||||
// Let's keep a fast access to the path
|
||||
int[][] path = new int[n_nodes][n_nodes];
|
||||
for (int i = 0; i < n_nodes; ++i)
|
||||
{
|
||||
for (int j = 0; j < n_nodes; ++j)
|
||||
{
|
||||
if (adj[i][j] == NO_EDGE)
|
||||
{
|
||||
path[i][j] = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
path[i][j] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Floyd-Warshall */
|
||||
for (int k = 0; k < n_nodes; ++k)
|
||||
{
|
||||
for (int i = 0; i < n_nodes; ++i)
|
||||
{
|
||||
for (int j = 0; j < n_nodes; ++j)
|
||||
{
|
||||
if (adj[i][j] > adj[i][k] + adj[k][j])
|
||||
{
|
||||
adj[i][j] = adj[i][k] + adj[k][j];
|
||||
path[i][j] = path[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Path from a given `start` to every other node in the graph
|
||||
ArrayDeque<Integer> indexes = new ArrayDeque<>();
|
||||
next_route:
|
||||
for (int end = 0; end < n_nodes; ++end)
|
||||
{
|
||||
indexes.clear();
|
||||
indexes.addFirst(end);
|
||||
|
||||
int current_end = end,
|
||||
previous;
|
||||
while (path[start][current_end] != start)
|
||||
{
|
||||
previous = path[start][current_end];
|
||||
if (previous == -1) // No possible path
|
||||
{
|
||||
continue next_route;
|
||||
}
|
||||
indexes.addFirst(previous);
|
||||
current_end = previous;
|
||||
}
|
||||
indexes.addFirst(start);
|
||||
System.out.println("Get to node " + end + " costs " + adj[start][end] + ".");
|
||||
}
|
26
InsertSort.java
Normal file
26
InsertSort.java
Normal file
@ -0,0 +1,26 @@
|
||||
import java.util.Arrays;
|
||||
|
||||
public class insertsort
|
||||
{
|
||||
public static void main (String[] args)
|
||||
{
|
||||
int[] in = {5,1,2,3};
|
||||
|
||||
System.out.println("Before insertion sort: " + Arrays.toString(in));
|
||||
|
||||
for (int i = 1; i < in.length; ++i)
|
||||
{
|
||||
int j = i - 1; // Ensure we don't get in a off by one error
|
||||
while (j >= 0 && in[j] > in[j + 1])
|
||||
{
|
||||
int t = in[j];
|
||||
in[j] = in[j+1];
|
||||
in[j+1] = t;
|
||||
--j; // Ensure that all the positions before are still correct
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("After insertion sort: " + Arrays.toString(in));
|
||||
}
|
||||
}
|
||||
|
34
Johnson.java
Normal file
34
Johnson.java
Normal file
@ -0,0 +1,34 @@
|
||||
// You have a graph G (original graph), with edge weight values v(u->w)
|
||||
// You must call this function with a helper graph with a special node
|
||||
// indexed 0 and zero-weight edges 0->w for all vertices w
|
||||
// Time complexity: O(N^2 * lg N + N*#Edges)
|
||||
// Returns APSP indexed as expected in the original graph (i.e.,
|
||||
// shifting everything -1 to exclude the special node of the helper graph)
|
||||
private static int[][]
|
||||
int_johnson (DirectedWeightedGraph<Integer> hg) throws Exception
|
||||
{
|
||||
// Finish the helper graph by running Bellman-Ford on it
|
||||
int[] h = hg.int_bellman_ford(0);
|
||||
|
||||
// Generate the tweaked graph
|
||||
for (int u = 1; u < hg.n_nodes; ++u) {
|
||||
hg.edges(u).forEach((w) -> {
|
||||
int edge_cost = (int) hg.weight(u, w).get(0);
|
||||
// Update edge's cost
|
||||
hg.link(u, w, edge_cost + h[u] - h[w]);
|
||||
}
|
||||
}
|
||||
|
||||
int [][] D = new int[hg.n_nodes-1][hg.n_nodes-1];
|
||||
|
||||
// Dijkstra on the tweaked graph
|
||||
for (int u = 0; u < g.n_nodes-1; ++u) {
|
||||
for (int w = 0; w < g.n_nodes-1; ++w) {
|
||||
int[] delta = hg.int_dijkstra(u+1);
|
||||
D[u][w] = delta[w+1] + h[w+1] - h[u+1];
|
||||
}
|
||||
}
|
||||
|
||||
// Johnson drops mic.
|
||||
return D;
|
||||
}
|
91
LIS.java
Normal file
91
LIS.java
Normal file
@ -0,0 +1,91 @@
|
||||
package ProgrammingChallenges.Uva;
|
||||
|
||||
import ProgrammingChallenges.FastPrint;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Scanner;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class
|
||||
UVA10534 {
|
||||
// https://stackoverflow.com/a/17660641
|
||||
// Time complexity: O(n*lg(n))
|
||||
public static int[]
|
||||
LIS(int[] a) {
|
||||
int n = a.length;
|
||||
int INF = 1000000000;
|
||||
int[] seq = new int[n];
|
||||
int[] d = new int[n + 1];
|
||||
d[0] = -INF;
|
||||
for (int i = 1; i < n + 1; ++i) {
|
||||
seq[i - 1] = 1;
|
||||
d[i] = INF;
|
||||
}
|
||||
|
||||
for (int i = 1; i < n + 1; ++i) {
|
||||
int low = 0,
|
||||
high = i;
|
||||
while (low <= high) {
|
||||
int mid = low + (high - low) / 2;
|
||||
if (d[mid] < a[i - 1]) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
high = mid - 1;
|
||||
}
|
||||
}
|
||||
d[low] = a[i - 1];
|
||||
seq[i - 1] = low;
|
||||
}
|
||||
|
||||
return seq;
|
||||
}
|
||||
|
||||
public static int[]
|
||||
reverse_arr(int[] seq) {
|
||||
/*int[] reverse_seq = new int[seq.length];
|
||||
for (int i = 0, j = seq.length-1; i < seq.length; ++i, --j)
|
||||
reverse_seq[j] = seq[i];*/
|
||||
return IntStream.range(0, seq.length)
|
||||
.map(i -> seq[seq.length - 1 - i])
|
||||
.toArray();
|
||||
}
|
||||
|
||||
public static int[]
|
||||
LDS(int[] seq) {
|
||||
/*int[] reverse_seq = IntStream.range(0, seq.length)
|
||||
.map(i -> seq[seq.length - 1 - i])
|
||||
.toArray();*/
|
||||
/*int[] reverse_seq = new int[seq.length];
|
||||
for (int i = 0, j = seq.length-1; i < seq.length; ++i, --j)
|
||||
reverse_seq[j] = seq[i];*/
|
||||
return reverse_arr(LIS(reverse_arr(seq)));
|
||||
}
|
||||
|
||||
public static void
|
||||
main(String[] args) {
|
||||
Scanner stdin = new Scanner(System.in);
|
||||
while (stdin.hasNext()) {
|
||||
// Input
|
||||
int N = stdin.nextInt();
|
||||
int[] seq = new int[N];
|
||||
for (int i = 0; i < N; ++i) {
|
||||
seq[i] = stdin.nextInt();
|
||||
}
|
||||
//System.out.println(Arrays.toString(seq));
|
||||
|
||||
// Process
|
||||
int[] lis = LIS(seq);
|
||||
int[] lds = LDS(seq);
|
||||
int ans = 0;
|
||||
for (int i = 0; i < N; ++i) {
|
||||
//System.out.println(lis[i] + " " + lds[i]);
|
||||
int min = Math.min(lis[i], lds[i]);
|
||||
ans = Math.max(ans, 2 * min - 1);
|
||||
}
|
||||
// Output
|
||||
FastPrint.out.println(ans);
|
||||
}
|
||||
FastPrint.out.close();
|
||||
}
|
||||
}
|
32
README.md
32
README.md
@ -1,3 +1,33 @@
|
||||
# JavaAlgorithms
|
||||
These are some Java code I wrote throughout my first degree in CompSci.
|
||||
These are some Java code I wrote throughout my first degree in Computer Science.
|
||||
There is some third party code properly credited and with its associated license.
|
||||
|
||||
## Files Descriptions
|
||||
|
||||
### Code I wrote
|
||||
* [Directed MultiGraph](DirectedMultiGraph.java) - Adjacency-list non-weighted directed multi-graphs (data structure)
|
||||
* [Directed Weighted Graph](DirectedWeightedGraph.java) - Adjacency-list n-weighted directed graphs (data structure)
|
||||
* [Dijkstra](DirectedWeightedGraph.java#L91) - Adjacency-list Dijkstra's algorithm implementation (SSC non-negative weights only)
|
||||
* [Prim](DirectedWeightedGraph.java#L173) - Adjacency-list Prim's algorithm implementation (MST)
|
||||
* [Bellman-Ford](DirectedWeightedGraph.java#L243) - Adjacency-list Bellman-ford (SSC)
|
||||
* [Floyd Warshall](FloydWarshall.java) - Adjacency-matrix Floyd Warshall (APSP)
|
||||
* [Johnson](Johnson.java) - Johnson's Algorithm (sparse graph APSP)
|
||||
* [Insert Sort](InsertSort.java) - An Insertion Sort implementation (sorting)
|
||||
* [DFS and Topological Sorting](DFS.java#L18) - Adjacency-list DFS with TopSort implementation (graph traversal and sorting)
|
||||
* [Kosaraju-Sharir](DFS.java#L48) - Adjacency-list Kosaraju-Sharir implementation (SCC)
|
||||
* [BFS non-directed SCC](bfs_scc.java) - Adjacency-list BFS implementation to identify SCC in a non-directed graph (graph traversal and SCC non-directed only)
|
||||
* [BFS non-weighted SSC](bfs_shortest_path.java) - Adjacency-list BFS for shortest path in a non-weighted graph (SSC non-weighted)
|
||||
* [LIS](LIS.java) - A Longest Increasing Sequence algorithm implmentation (substring)
|
||||
* [Collections Count If](collections_count_if.java#L46) - Counts elements for which predicate p returns true (collection utility)
|
||||
|
||||
|
||||
### Third party code
|
||||
* [Couple](Couple.java) - A AOSP class to handle 2-tuples
|
||||
* [Segment Tree](SegmentTree.java) - A Segment Tree data structure implementation derived from Segewick and Wayne's Algorithms, 4th ed. book
|
||||
* [ValueThenKeyComparator](ValueThenKeyComparator.java) - A Comparator that sorts Map.Entry objects with Comparable keys and values, first by value, then by key
|
||||
* [FastScanner](FastScanner.java) - Fast Input from STDIN in Java
|
||||
* [FastPrint](FastPrint.java) - Fast Output from STDOUT in Java
|
||||
|
||||
### Example code
|
||||
* [Activity Minimum Gap Schedulling](minimum_gap_schedulling.java) - Activity Minimum Gap Schedulling implementation (sorting)
|
||||
* [Knapsack](knapsack.java) - Knapsack approximation solution using conditional binary search (search and optimization)
|
||||
|
318
SegmentTree.java
Normal file
318
SegmentTree.java
Normal file
@ -0,0 +1,318 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* A segment tree data structure.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* The {@code SegmentTree} class is a structure for efficient search of cumulative data.
|
||||
* It performs Range Min, Max, Sum and Multiplication Queries in O(log(n)) time.
|
||||
* <p>
|
||||
* Also it has been develop with {@code LazyPropagation} for range updates, which means
|
||||
* when you perform update operations over a range, the update process affects the least nodes as possible
|
||||
* so that the bigger the range you want to update the less time it consumes to update it. Eventually those changes will be propagated
|
||||
* to the children and the whole array will be up to date.
|
||||
* <p>
|
||||
* Example:
|
||||
* <p>
|
||||
* SegmentTreeHeap st = new SegmentTreeHeap(new Integer[]{1,3,4,2,1, -2, 4});
|
||||
* st.update(0,3, 1)
|
||||
* In the above case only the node that represents the range [0,3] will be updated (and not their children) so in this case
|
||||
* the update task will be less than n*log(n)
|
||||
* <p>
|
||||
* Memory usage: O(n)
|
||||
*
|
||||
* @author Ricardo Pacheco (base code)
|
||||
* @author Diogo Cordeiro (implemented range max and multiplication queries, plus other minor changes)
|
||||
* @link https://algs4.cs.princeton.edu/99misc/SegmentTree.java.html
|
||||
*/
|
||||
public class SegmentTree {
|
||||
|
||||
private final STNode[] heap;
|
||||
private final int[] array;
|
||||
|
||||
/**
|
||||
* Time-Complexity: O(n*log(n))
|
||||
*
|
||||
* @param array the Initialization array
|
||||
*/
|
||||
public SegmentTree(int[] array) {
|
||||
this.array = Arrays.copyOf(array, array.length);
|
||||
// The max size of this array is about 2 * 2 ^ log2(n) + 1
|
||||
int size = (int) (2 * Math.pow(2.0, Math.floor((Math.log(array.length) / Math.log(2.0)) + 1)));
|
||||
heap = new STNode[size];
|
||||
build(1, 0, array.length);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return array.length;
|
||||
}
|
||||
|
||||
// Initialize the Nodes of the Segment tree
|
||||
private void build(int v, int from, int size) {
|
||||
heap[v] = new STNode();
|
||||
heap[v].from = from;
|
||||
heap[v].to = from + size - 1;
|
||||
|
||||
if (size == 1) {
|
||||
heap[v].sum = array[from];
|
||||
heap[v].mul = array[from];
|
||||
heap[v].min = array[from];
|
||||
heap[v].max = array[from];
|
||||
} else {
|
||||
// Build childs
|
||||
build(2 * v, from, size / 2);
|
||||
build(2 * v + 1, from + size / 2, size - size / 2);
|
||||
|
||||
heap[v].sum = heap[2 * v].sum + heap[2 * v + 1].sum;
|
||||
heap[v].mul = heap[2 * v].mul * heap[2 * v + 1].mul;
|
||||
// min = min of the children
|
||||
heap[v].min = Math.min(heap[2 * v].min, heap[2 * v + 1].min);
|
||||
// max = max of the children
|
||||
heap[v].max = Math.max(heap[2 * v].max, heap[2 * v + 1].max);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Range Sum Query
|
||||
* <p>
|
||||
* Time-Complexity: O(log(n))
|
||||
*
|
||||
* @param from from index
|
||||
* @param to to index
|
||||
* @return sum
|
||||
*/
|
||||
public int rsq(int from, int to) {
|
||||
return rsq(1, from, to);
|
||||
}
|
||||
|
||||
private int rsq(int v, int from, int to) {
|
||||
STNode n = heap[v];
|
||||
|
||||
// If you did a range update that contained this node, you can infer the Sum without going down the tree
|
||||
if (n.pendingVal != null && contains(n.from, n.to, from, to)) {
|
||||
return (to - from + 1) * n.pendingVal;
|
||||
}
|
||||
|
||||
if (contains(from, to, n.from, n.to)) {
|
||||
return heap[v].sum;
|
||||
}
|
||||
|
||||
if (intersects(from, to, n.from, n.to)) {
|
||||
propagate(v);
|
||||
int leftSum = rsq(2 * v, from, to);
|
||||
int rightSum = rsq(2 * v + 1, from, to);
|
||||
|
||||
return leftSum + rightSum;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Range Multiplication Query
|
||||
* <p>
|
||||
* Time-Complexity: O(log(n))
|
||||
*
|
||||
* @param from from index
|
||||
* @param to to index
|
||||
* @author Diogo Peralta Cordeiro <diogo@fc.up.pt>
|
||||
* @return multiplication
|
||||
*/
|
||||
public int rmq(int from, int to) {
|
||||
return rmq(1, from, to);
|
||||
}
|
||||
|
||||
private int rmq(int v, int from, int to) {
|
||||
STNode n = heap[v];
|
||||
|
||||
// If you did a range update that contained this node, you can infer the Product without going down the tree
|
||||
if (n.pendingVal != null && contains(n.from, n.to, from, to)) {
|
||||
return (to - from + 1) * n.pendingVal;
|
||||
}
|
||||
|
||||
if (contains(from, to, n.from, n.to)) {
|
||||
return heap[v].mul;
|
||||
}
|
||||
|
||||
if (intersects(from, to, n.from, n.to)) {
|
||||
propagate(v);
|
||||
int leftMul = rmq(2 * v, from, to);
|
||||
int rightMul = rmq(2 * v + 1, from, to);
|
||||
|
||||
return leftMul * rightMul;
|
||||
}
|
||||
|
||||
return 1; // neutral element
|
||||
}
|
||||
|
||||
/**
|
||||
* Range Min Query
|
||||
* <p>
|
||||
* Time-Complexity: O(log(n))
|
||||
*
|
||||
* @param from from index
|
||||
* @param to to index
|
||||
* @return min
|
||||
*/
|
||||
public int rMinQ(int from, int to) {
|
||||
return rMinQ(1, from, to);
|
||||
}
|
||||
|
||||
private int rMinQ(int v, int from, int to) {
|
||||
STNode n = heap[v];
|
||||
|
||||
|
||||
// If you did a range update that contained this node, you can infer the Min value without going down the tree
|
||||
if (n.pendingVal != null && contains(n.from, n.to, from, to)) {
|
||||
return n.pendingVal;
|
||||
}
|
||||
|
||||
if (contains(from, to, n.from, n.to)) {
|
||||
return heap[v].min;
|
||||
}
|
||||
|
||||
if (intersects(from, to, n.from, n.to)) {
|
||||
propagate(v);
|
||||
int leftMin = rMinQ(2 * v, from, to);
|
||||
int rightMin = rMinQ(2 * v + 1, from, to);
|
||||
|
||||
return Math.min(leftMin, rightMin);
|
||||
}
|
||||
|
||||
return 1000000000; // 1e9 to avoid overflow
|
||||
}
|
||||
|
||||
/**
|
||||
* Range Max Query
|
||||
* <p>
|
||||
* Time-Complexity: O(log(n))
|
||||
*
|
||||
* @param from from index
|
||||
* @param to to index
|
||||
* @author Diogo Peralta Cordeiro <diogo@fc.up.pt>
|
||||
* @return max
|
||||
*/
|
||||
public int rMaxQ(int from, int to) {
|
||||
return rMaxQ(1, from, to);
|
||||
}
|
||||
|
||||
private int rMaxQ(int v, int from, int to) {
|
||||
STNode n = heap[v];
|
||||
|
||||
// If you did a range update that contained this node, you can infer the Max value without going down the tree
|
||||
if (n.pendingVal != null && contains(n.from, n.to, from, to))
|
||||
return n.pendingVal;
|
||||
if (contains(from, to, n.from, n.to))
|
||||
return heap[v].max;
|
||||
if (intersects(from, to, n.from, n.to)) {
|
||||
propagate(v);
|
||||
int leftMax = rMaxQ(2 * v, from, to);
|
||||
int rightMax = rMaxQ(2 * v + 1, from, to);
|
||||
return Math.max(leftMax, rightMax);
|
||||
}
|
||||
return -1000000000; // 1e9 to avoid overflow
|
||||
}
|
||||
|
||||
/**
|
||||
* Range Update Operation.
|
||||
* With this operation you can update either one position or a range of positions with a given number.
|
||||
* The update operations will update the less it can to update the whole range (Lazy Propagation).
|
||||
* The values will be propagated lazily from top to bottom of the segment tree.
|
||||
* This behavior is really useful for updates on portions of the array
|
||||
* <p>
|
||||
* Time-Complexity: O(log(n))
|
||||
*
|
||||
* @param from from index
|
||||
* @param to to index
|
||||
* @param value value
|
||||
*/
|
||||
public void update(int from, int to, int value) {
|
||||
update(1, from, to, value);
|
||||
}
|
||||
|
||||
private void update(int v, int from, int to, int value) {
|
||||
|
||||
// The Node of the heap tree represents a range of the array with bounds: [n.from, n.to]
|
||||
STNode n = heap[v];
|
||||
|
||||
/**
|
||||
* If the updating-range contains the portion of the current Node We lazily update it.
|
||||
* This means We do NOT update each position of the vector, but update only some temporal
|
||||
* values into the Node; such values into the Node will be propagated down to its children only when they need to.
|
||||
*/
|
||||
if (contains(from, to, n.from, n.to)) {
|
||||
change(n, value);
|
||||
}
|
||||
|
||||
if (n.size() == 1) return;
|
||||
|
||||
if (intersects(from, to, n.from, n.to)) {
|
||||
/**
|
||||
* Before keeping going down to the tree We need to propagate the
|
||||
* the values that have been temporally/lazily saved into this Node to its children
|
||||
* So that when We visit them the values are properly updated
|
||||
*/
|
||||
propagate(v);
|
||||
|
||||
update(2 * v, from, to, value);
|
||||
update(2 * v + 1, from, to, value);
|
||||
|
||||
n.sum = heap[2 * v].sum + heap[2 * v + 1].sum;
|
||||
n.mul = heap[2 * v].mul * heap[2 * v + 1].mul;
|
||||
n.min = Math.min(heap[2 * v].min, heap[2 * v + 1].min);
|
||||
n.max = Math.max(heap[2 * v].max, heap[2 * v + 1].max);
|
||||
}
|
||||
}
|
||||
|
||||
// Propagate temporal values to children
|
||||
private void propagate(int v) {
|
||||
STNode n = heap[v];
|
||||
|
||||
if (n.pendingVal != null) {
|
||||
change(heap[2 * v], n.pendingVal);
|
||||
change(heap[2 * v + 1], n.pendingVal);
|
||||
n.pendingVal = null; //unset the pending propagation value
|
||||
}
|
||||
}
|
||||
|
||||
// Save the temporal values that will be propagated lazily
|
||||
private void change(STNode n, int value) {
|
||||
n.pendingVal = value;
|
||||
n.sum = n.size() * value;
|
||||
n.mul = n.size() * value;
|
||||
n.min = value;
|
||||
n.max = value;
|
||||
array[n.from] = value;
|
||||
|
||||
}
|
||||
|
||||
// Test if the range1 contains range2
|
||||
private boolean contains(int from1, int to1, int from2, int to2) {
|
||||
return from2 >= from1 && to2 <= to1;
|
||||
}
|
||||
|
||||
// check inclusive intersection, test if range1[from1, to1] intersects range2[from2, to2]
|
||||
private boolean intersects(int from1, int to1, int from2, int to2) {
|
||||
return from1 <= from2 && to1 >= from2 // (.[..)..] or (.[...]..)
|
||||
|| from1 >= from2 && from1 <= to2; // [.(..]..) or [..(..)..
|
||||
}
|
||||
|
||||
// The Node class represents a partition range of the array.
|
||||
static class STNode {
|
||||
int sum, mul;
|
||||
int min, max;
|
||||
// Here we store the value that will be propagated lazily
|
||||
Integer pendingVal = null;
|
||||
int from;
|
||||
int to;
|
||||
|
||||
int size() {
|
||||
return to - from + 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
17
ValueThenKeyComparator.java
Normal file
17
ValueThenKeyComparator.java
Normal file
@ -0,0 +1,17 @@
|
||||
import java.util.Comparator;
|
||||
import java.util.Map;
|
||||
|
||||
// from: https://stackoverflow.com/a/3074324
|
||||
public class ValueThenKeyComparator<K extends Comparable<? super K>,
|
||||
V extends Comparable<? super V>>
|
||||
implements Comparator<Map.Entry<K, V>> {
|
||||
|
||||
public int compare(Map.Entry<K, V> a, Map.Entry<K, V> b) {
|
||||
int cmp1 = b.getValue().compareTo(a.getValue());
|
||||
if (cmp1 != 0) {
|
||||
return cmp1;
|
||||
} else {
|
||||
return a.getKey().compareTo(b.getKey());
|
||||
}
|
||||
}
|
||||
}
|
22
bfs_scc.java
Normal file
22
bfs_scc.java
Normal file
@ -0,0 +1,22 @@
|
||||
// Pre-Process answers with a BFS (only possible if the graph is undirected)
|
||||
int[] answers = new int[n];
|
||||
ArrayDeque<Integer> queue = new ArrayDeque<>(n); // Queue
|
||||
for (int s = n-1; s >= 0; --s)
|
||||
{
|
||||
if (answers[s] < s)
|
||||
answers[s] = s;
|
||||
queue.addFirst(s);
|
||||
g.seen[s] = true;
|
||||
while(!queue.isEmpty())
|
||||
{
|
||||
int u = queue.removeLast();
|
||||
this.edges(u).forEach((w) -> {
|
||||
if (!g.verts[w].seen)
|
||||
{
|
||||
queue.addFirst(w);
|
||||
g.seen[w] = true;
|
||||
answers[w] = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
54
bfs_shortest_path.java
Normal file
54
bfs_shortest_path.java
Normal file
@ -0,0 +1,54 @@
|
||||
public class bfs_shortest_path
|
||||
{
|
||||
public static void main (String[] args)
|
||||
{
|
||||
int n_nodes = 42;
|
||||
boolean[] come_from = new boolean[n_nodes];
|
||||
DirectedMultiGraph graph = new DirectedMultiGraph(n_nodes, true);
|
||||
|
||||
// Input
|
||||
Scanner stdin = new Scanner(System.in);
|
||||
int a = stdin.nextInt(), b, graph_root = a;
|
||||
while ((b = stdin.nextInt()) != 0)
|
||||
{
|
||||
graph.link_first(a, b);
|
||||
|
||||
a = b;
|
||||
}
|
||||
int destination = a;
|
||||
|
||||
// BFS
|
||||
ArrayDeque<Integer> to_explore = new ArrayDeque<>(); // Queue
|
||||
to_explore.addFirst(graph_root);
|
||||
graph.seen[graph_root] = true;
|
||||
while (!to_explore.isEmpty())
|
||||
{
|
||||
int u = to_explore.removeLast();
|
||||
this.edges(u).forEach((w) ->
|
||||
{
|
||||
if (!g.seen[w])
|
||||
{
|
||||
to_explore.addFirst(w);
|
||||
g.seen[w] = true;
|
||||
come_from[w] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Output
|
||||
ArrayDeque<Integer> path = new ArrayDeque<>();
|
||||
path.addFirst(destination);
|
||||
while(path.getFirst() != graph_root)
|
||||
{
|
||||
path.addFirst(graph.verts[path.getFirst()].come_from);
|
||||
}
|
||||
System.out.println("Output:");
|
||||
for (int i : path)
|
||||
{
|
||||
System.out.println(i);
|
||||
}
|
||||
|
||||
// No leaks
|
||||
stdin.close();
|
||||
}
|
||||
}
|
56
collections_count_if.java
Normal file
56
collections_count_if.java
Normal file
@ -0,0 +1,56 @@
|
||||
package ProgrammingChallenges.Uva;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.IntPredicate;
|
||||
|
||||
class UVA11286 {
|
||||
static final int modules_per_term = 5;
|
||||
|
||||
public static void
|
||||
main(String[] args) {
|
||||
Scanner stdin = new Scanner(System.in);
|
||||
|
||||
// <Combination, Frequency>
|
||||
Map<List<Integer>, Integer> freshers_modules = new HashMap<>();
|
||||
|
||||
while (stdin.hasNext()) {
|
||||
int number_of_freshers = stdin.nextInt();
|
||||
if (number_of_freshers == 0) {
|
||||
break; // This was the last test case
|
||||
}
|
||||
freshers_modules.clear(); // Reset our data structure
|
||||
|
||||
for (int i = 0; i < number_of_freshers; ++i) {
|
||||
List<Integer> modules = new ArrayList<>();
|
||||
for (int j = 0; j < modules_per_term; ++j) {
|
||||
int x = stdin.nextInt();
|
||||
modules.add(x);
|
||||
}
|
||||
Collections.sort(modules);
|
||||
freshers_modules.merge(modules, 1, Integer::sum);
|
||||
}
|
||||
|
||||
// Most popular pair
|
||||
Map.Entry<List<Integer>, Integer> most_popular_module = Collections.max(freshers_modules.entrySet(), Map.Entry.comparingByValue());
|
||||
// How many are as popular?
|
||||
int max_students = most_popular_module.getValue();
|
||||
int number_of_equally_popular_modules = collections_count_if(freshers_modules.values(), (a) -> a == max_students);
|
||||
// This is the sh1ttiest prompt ever...
|
||||
//System.out.println("max_students = "+max_students+"\nnumber_of_equally_popular_modules = "+number_of_equally_popular_modules+"\nnumber_of_freshers = "+number_of_freshers);
|
||||
System.out.println(max_students * number_of_equally_popular_modules);
|
||||
}
|
||||
stdin.close();
|
||||
}
|
||||
|
||||
public static int
|
||||
collections_count_if(Collection<Integer> coll, IntPredicate op) {
|
||||
int count = 0;
|
||||
for (Integer v : coll) {
|
||||
if (op.test((v))) {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
}
|
65
knapsack.java
Normal file
65
knapsack.java
Normal file
@ -0,0 +1,65 @@
|
||||
import java.util.Arrays;
|
||||
|
||||
public class DAA011 {
|
||||
public static void
|
||||
main(String[] args)
|
||||
{
|
||||
FastScanner stdin = new FastScanner(System.in);
|
||||
int n = stdin.nextInt();
|
||||
int[] dist = new int[n];
|
||||
int max = 0;
|
||||
|
||||
for (int i = 0; i < n; ++i) {
|
||||
dist[i] = stdin.nextInt();
|
||||
max += dist[i];
|
||||
}
|
||||
|
||||
for (int p = stdin.nextInt(); p > 0; --p) {
|
||||
FastPrint.out.println(cond_bsearch(dist, 0, max, stdin.nextInt()));
|
||||
}
|
||||
|
||||
FastPrint.out.close();
|
||||
}
|
||||
|
||||
public static int
|
||||
cond_bsearch(int[] haystack, int l, int r, int k)
|
||||
{
|
||||
//System.out.println(Arrays.toString(haystack));
|
||||
//System.out.println("l: "+l+" | r: "+r+" | k: "+k);
|
||||
while (l < r) {
|
||||
int mid = l + (r - l) / 2;
|
||||
|
||||
if (cond(haystack, mid, k)) {
|
||||
r = mid;
|
||||
} else {
|
||||
l = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
//System.out.println("l: "+l+" | r: "+r+" | k: "+k);
|
||||
//return cond(haystack, l, k) ? l : -1;
|
||||
return l;
|
||||
}
|
||||
|
||||
public static boolean
|
||||
cond(int[] dist, int needle, int k)
|
||||
{
|
||||
//System.out.println("needle: "+needle);
|
||||
int acc = 0;
|
||||
int partitions = 0;
|
||||
for (int i : dist) { // 10
|
||||
acc += i; // 18
|
||||
if (acc > needle) { // 18 > 8 = true
|
||||
acc = i; // This one isn't part of the partition we've just created = 10
|
||||
if (i > needle) return false;
|
||||
if (++partitions > k) { //part = 7 > 10 = false
|
||||
//System.out.println("last number of partitions: "+partitions);
|
||||
return false; // early break to save time
|
||||
}
|
||||
}
|
||||
//System.out.println("i: "+i+" | acc: "+acc+" | part: "+partitions);
|
||||
}
|
||||
//System.out.println("last_number of partitions: "+partitions);
|
||||
return partitions < k;
|
||||
}
|
||||
}
|
85
minimum_gap_schedulling.java
Normal file
85
minimum_gap_schedulling.java
Normal file
@ -0,0 +1,85 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
class Activity implements Comparable<Activity>
|
||||
{
|
||||
int start, end;
|
||||
|
||||
Activity(int start, int end)
|
||||
{
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "["+start+","+end+"]";
|
||||
}
|
||||
|
||||
@Override
|
||||
// Early Start
|
||||
// Longest size
|
||||
public int compareTo(Activity b) {
|
||||
int early_start = Integer.compare(this.start, b.start);
|
||||
if (early_start == 0)
|
||||
return Integer.compare(b.end-b.start, this.end-this.start);
|
||||
return early_start;
|
||||
}
|
||||
|
||||
public boolean
|
||||
intersects (Activity b)
|
||||
{
|
||||
return this.start <= b.start ||
|
||||
b.end < this.start;
|
||||
}
|
||||
}
|
||||
|
||||
class
|
||||
DAA013
|
||||
{
|
||||
public static void
|
||||
main (String[] args)
|
||||
{
|
||||
FastScanner stdin = new FastScanner(System.in);
|
||||
|
||||
int M = stdin.nextInt(), // tamanho do segmento a cobrir
|
||||
N = stdin.nextInt(); // qtd de segmentos
|
||||
|
||||
Activity[] acts = new Activity[N];
|
||||
for (int i = 0; i < N; ++i)
|
||||
{
|
||||
int l = stdin.nextInt(),
|
||||
r = stdin.nextInt();
|
||||
acts[i] = new Activity(l, r);
|
||||
}
|
||||
|
||||
// Sort them
|
||||
Arrays.sort(acts);
|
||||
//System.out.println(Arrays.toString(acts));
|
||||
|
||||
// Cobertura mínima
|
||||
int end = 0;
|
||||
Activity x = acts[0];
|
||||
List<Activity> path = new ArrayList<>();
|
||||
while (end < M)
|
||||
{
|
||||
for (Activity candidate : acts)
|
||||
{
|
||||
if (candidate.start <= end)
|
||||
{
|
||||
if (candidate.end >= x.end)
|
||||
{
|
||||
x = candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
end = x.end;
|
||||
path.add(x);
|
||||
}
|
||||
//System.out.println(path);
|
||||
|
||||
FastPrint.out.println(path.size());
|
||||
FastPrint.out.close();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user