import java.util.ArrayList; import java.util.Comparator; import java.util.PriorityQueue; import java.util.Scanner; class Edge { public Edge(int to, double dist, double speed) { this.to = to; this.dist = dist; this.speed = speed; } int to; double dist; double speed; public double distance(double extraV) { return dist / (speed + extraV); } } class PQEdge { int to; double dist; public PQEdge(int to, double dist) { this.to = to; this.dist = dist; } } class Vertex { ArrayList edges; public Vertex() { this.edges = new ArrayList<>(); } public void addEdge(int to, int l, int v) { edges.add(new Edge(to, l, v)); } @Override public String toString() { return edges.toString(); } } public class NickyEnMark { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int m = scanner.nextInt(); int t = scanner.nextInt(); ArrayList graph = new ArrayList<>(); graph.add(new Vertex()); for (int i = 0; i < n; i++) { graph.add(new Vertex()); } for (int i = 0; i < m; i++) { int a = scanner.nextInt(); int b = scanner.nextInt(); int l = scanner.nextInt(); int v = scanner.nextInt(); graph.get(a).addEdge(b, l, v); graph.get(b).addEdge(a, l, v); } double dist = distance(graph, n, 0); if (dist <= t) { System.out.println(0); return; } double lower = 0; double upper = 10e13; double mid = 0; for (int i = 0; i < 70; i++) { mid = (lower + upper) / 2; dist = distance(graph, n, mid); // System.out.println(dist + " - " + mid); if (dist > t) { lower = mid; } else { upper = mid; } } System.out.println(mid); } private static double distance(ArrayList graph, int n, double extraV) { double[] distances = new double[n + 1]; boolean[] done = new boolean[n + 1]; for (int i = 0; i < graph.size(); i++) { distances[i] = Double.MAX_VALUE; } distances[1] = 0; PriorityQueue q = new PriorityQueue<>(Comparator.comparing(e -> e.dist)); q.add(new PQEdge(1, 0)); while (!q.isEmpty()) { PQEdge e = q.poll(); if (e.to == n) { return distances[n]; } if (done[e.to]) { continue; } done[e.to] = true; for (Edge ee : graph.get(e.to).edges) { double newDist = distances[e.to] + ee.distance(extraV); if (newDist < distances[ee.to]) { distances[ee.to] = newDist; q.add(new PQEdge(ee.to, newDist)); } } } return distances[n]; } }