import java.util.ArrayList; import java.util.PriorityQueue; import java.util.Scanner; public class SignalStrength { Scanner in = new Scanner(System.in); Vertex[] switches; public static void main(String[] args) { new SignalStrength().start(); } private void start() { int curNetwork = 1; while (true) { int N = in.nextInt(); if (N <= 0) break; switches = new Vertex[N]; for (int i = 0; i < switches.length; i++) { switches[i] = new Vertex(i); } for (int i = 0; i < switches.length; i++) { switches[i].myGain = 1 / in.nextFloat(); // reciprocal int numOutputs = in.nextInt(); for (int j = 0; j < numOutputs; j++) { int out = in.nextInt(); float loss = 1 / in.nextFloat(); // reciprocal switches[i].myOutputs.add(new Edge(switches[out], loss)); } } solve(curNetwork); curNetwork ++; } } private void solve(int curNetwork) { computePaths(switches[0]); float ans = 1 / switches[switches.length - 1].myOutput; System.out.printf("Network %d: %.2f\n", curNetwork, ans); } // Dijkstra's algorithm void computePaths(Vertex source) { source.myOutput = source.myGain; // input signal of 1.0 PriorityQueue Q = new PriorityQueue(); Q.add(source); while (! Q.isEmpty()) { Vertex U = Q.poll(); for (Edge E: U.myOutputs) { Vertex V = E.myTarget; float strengthThroughU = U.myOutput * E.myWeight * V.myGain + 1; if (strengthThroughU < V.myOutput) { Q.remove(V); V.myOutput = strengthThroughU; V.myPrevious = U; Q.add(V); } } } } class Vertex implements Comparable { // Unique index identifying this switch int myIndex; // Array of edges connecting to adjacent vertices ArrayList myOutputs; // Output from switch float myOutput; // Amplification gain float myGain; // Previous vertex Vertex myPrevious; // Constructor public Vertex(int index) { myIndex = index; myOutputs = new ArrayList(); myOutput = Integer.MAX_VALUE; } // Comparator public int compareTo(Vertex other) { float test = this.myOutput - other.myOutput; if (test > 0) return 1; else if (test < 0) return -1; else return 0; } } class Edge { // Destination Vertex myTarget; // Edge weight (distance) float myWeight; // Constructor public Edge(Vertex target, float weight) { myTarget = target; myWeight = weight; } } }