Problem:
Problem E: Hide-and-seek

Hide-and-seek is a children’s game. Players hide here and there, and one player called it tries to find all
the other players.

Now you played it and found all the players, so it’s turn to hide from it. Since you have got tired of
running around for finding players, you don’t want to play it again. So you are going to hide yourself at
the place as far as possible from it. But where is that?

Your task is to find the place and calculate the maximum possible distance from it to the place to hide.

Input

The input contains a number of test cases.

The first line of each test case contains a positive integer N (N ≤ 1000). The following N lines give
the map where hide-and-seek is played. The map consists of N corridors. Each line contains four real
numbers x1, y1, x2, and y2, where (x1, y1 ) and (x2, y2 ) indicate the two end points of the corridor. All
corridors are straight, and their widths are negligible. After these N lines, there is a line containing two
real numbers sx and sy, indicating the position of it. You can hide at an arbitrary place of any corridor,
and it always walks along corridors. Numbers in the same line are separated by a single space.

It is guaranteed that its starting position (sx, sy) is located on some corridor and linked to all corridors
directly or indirectly.

The end of the input is indicated by a line containing a single zero.

Output

For each test case, output a line containing the distance along the corridors from ‘it”s starting position
to the farthest position. The value may contain an error less than or equal to 0.001. You may print any
number of digits below the decimal point.

Sample Input

2
0 0 3 3
0 4 3 1
1 1
0

Output for the Sample Input

4.243

Solution in Rust (judge verdict: Accepted)

extern crate core;

use std::fmt;
use std::cmp::{Ordering, min, max};
use std::fmt::{Display, Error, Formatter};
use std::f32::MAX;
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut};
use std::collections::{BTreeMap, VecDeque, BinaryHeap};

fn show<T: Display>(vec: &Vec<T>) {
    if vec.is_empty() {
        println!("[]");
    }else {
        print!("[{}", vec[0]);
        for i in 1 .. vec.len() {
            print!(", {}", vec[i]);
        }
        println!("]");
    }
}
fn show2<T: Display>(vec: &Vec<Vec<T>>) {
    if vec.is_empty() {
        println!("[]");
    }else {
        for l in vec {
            show(l);
        }
    }
}
macro_rules! read_line{
    () => {{
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).ok();
        line
    }};
    (delimiter: ' ') => {
        read_line!().split_whitespace().map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (delimiter: $p:expr) => {
        read_line!().split($p).map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (' ') => {
        read_line!(delimiter: ' ')
    };
    ($delimiter:expr) => {
        read_line!(delimiter: $delimiter)
    };
    (' '; $ty:ty) => {
        read_line!().split_whitespace().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
    ($delimiter:expr; $ty:ty) => {
        read_line!($delimiter).into_iter().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
}
macro_rules! read_value{
    () => {
        read_line!().trim().parse().ok().unwrap()
    }
}
macro_rules! let_all {
    ($($n:ident:$t:ty),*) => {
        let line = read_line!(delimiter: ' ');
        let mut iter = line.iter();
        $(let $n:$t = iter.next().unwrap().parse().ok().unwrap();)*
    };
}
macro_rules! let_mut_all {
    ($($n:ident:$t:ty),*) => {
        let line = read_line!(delimiter: ' ');
        let mut iter = line.iter();
        $(let mut $n:$t = iter.next().unwrap().parse().ok().unwrap();)*
    };
}

const EPSILON: f64 = 0.000001;
#[derive(Copy, Clone)]
struct Point{
    x: f64, y: f64
}
impl Point {
    fn new(x: f64, y: f64) -> Point {
        Point{x: x, y: y}
    }
    fn distance_from(&self, other: &Point) -> f64 {
        ((self.x - other.x) * (self.x - other.x) + (self.y - other.y) * (self.y - other.y)).sqrt()
    }
}
impl Display for Point {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "(x: {}, y: {})", self.x, self.y)
    }
}
struct Line {
    a: f64, b: f64, c: f64
}
struct Edge {
    from: Point, to: Point, pub line: Line
}
impl Edge {
    fn new(from: Point, to: Point) -> Edge {
        Edge{from: from, to: to, line: Line::by_two_line(&from, &to)}
    }
    fn cross_point(&self, other: &Self) -> Option<Point> {
        match self.line.cross_point(&other.line) {
            Some(p) if (p.x - self.from.x) * (p.x - self.to.x) <= EPSILON && (p.y - self.from.y) * (p.y - self.to.y) <= EPSILON => Some(p),
            _ => None
        }
    }
    fn is_on_edge(&self, other: &Point) -> bool {
        self.line.is_on_line(other) && (other.x - self.from.x) * (other.x - self.to.x) <= EPSILON && (other.y - self.from.y) * (other.y - self.to.y) <= EPSILON
    }
}
impl Line {
    fn by_two_line(a: &Point, b: &Point) -> Line {
        Line{a: b.y - a.y, b: a.x - b.x, c: a.y * b.x - a.x * b.y}
    }
    fn cross_point(&self, other: &Line) -> Option<Point> {
        if self.is_parallel(other) {
            None
        }else {
            let d = self.a * other.b - self.b * other.a;
            Some(Point{x: (self.b * other.c - self.c * other.b) / d, y: (self.c * other.a - self.a * other.c) / d})
        }
    }
    fn is_parallel(&self, other: &Line) -> bool {
        (self.a * other.b - self.b * other.a).abs() <= EPSILON
    }
    fn is_on_line(&self, other: &Point) -> bool {
        (self.a * other.x + self.b * other.y + self.c).abs() <= EPSILON
    }
}
struct CrossPoint {
    point: Point, to: usize,
}
struct ValueWithKey<K, V> {
    key: K, value: V
}
impl <K, V> ValueWithKey<K, V> {
    fn new(key: K, value: V) -> ValueWithKey<K, V> {
        ValueWithKey{key: key, value: value}
    }
}
impl <K: Copy, V: Copy> Copy for ValueWithKey<K, V> {}
impl <K: Clone, V: Clone> Clone for ValueWithKey<K, V>{
    fn clone(&self) -> Self {
        ValueWithKey{key: self.key.clone(), value: self.value.clone()}
    }
}
impl <K: PartialOrd, V> Ord for ValueWithKey<K, V> {
    fn cmp(&self, other: &Self) -> Ordering {
        other.key.partial_cmp(&self.key).unwrap()
    }
}
impl <K: PartialOrd, V> PartialOrd for ValueWithKey<K, V> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        other.key.partial_cmp(&self.key)
    }
}
impl <K: PartialOrd, V> PartialEq for ValueWithKey<K, V> {
    fn eq(&self, other: &Self) -> bool {
        other.key.eq(&self.key)
    }
}
impl <K: PartialOrd, V> Eq for ValueWithKey<K, V> {}
#[derive(Copy, Clone)]
struct Path {
    to: usize, cost: f64,
}
fn min_f64(a: f64, b: f64) -> f64 {
    if a > b {
        b
    }else {
        a
    }
}
fn main() {
    loop {
        let_all!(n: usize);
        if n == 0 {
            return
        }
        let mut edges = Vec::with_capacity(n);
        for _ in 0 .. n {
            let_all!(x1: f64, y1: f64, x2: f64, y2: f64);
            edges.push(Edge::new(Point::new(x1, y1), Point::new(x2, y2)));
        }
        let_all!(x: f64, y: f64);
        let start = Point::new(x, y);
        let mut points = vec![Vec::new(); 2 * n + n * (n - 1) / 2 + 1];
        let mut cross = Vec::with_capacity(n);
        for i in 0 .. n {
            let mut cross_points = vec![ValueWithKey{key: 0_f64, value: i * 2}, ValueWithKey{key: edges[i].from.distance_from(&edges[i].to), value: i * 2 + 1}];
            for j in 0 .. n {
                if i != j {
                    if let Some(cp) = edges[i].cross_point(&edges[j]) {
                        if i > j {
                            cross_points.push(ValueWithKey { key: edges[i].from.distance_from(&cp), value: 2 * n + i * (i - 1) / 2 + j });
                        }else {
                            cross_points.push(ValueWithKey { key: edges[i].from.distance_from(&cp), value: 2 * n + j * (j - 1) / 2 + i });
                        }
                    }
                }
            }
            if edges[i].is_on_edge(&start) {
                cross_points.push(ValueWithKey{key: edges[i].from.distance_from(&start), value: 2 * n + n * (n - 1) / 2});
            }
            cross_points.sort();
            for j in 1 .. cross_points.len() {
                //println!("set edge {}, {}, distance {}", cross_points[j].value, cross_points[j - 1].value, cross_points[j - 1].key - cross_points[j].key);
                points[cross_points[j].value].push(Path{to: cross_points[j - 1].value, cost: cross_points[j - 1].key - cross_points[j].key});
                points[cross_points[j - 1].value].push(Path{to: cross_points[j].value, cost: cross_points[j - 1].key - cross_points[j].key});
            }
            cross.push(cross_points);
        }
        let mut memo = vec![std::f64::MAX; points.len()];
        let mut queue = BinaryHeap::new();
        memo[points.len() - 1] = 0_f64;
        queue.push(ValueWithKey{key: 0_f64, value: points.len() - 1});
        while let Some(ValueWithKey{key: distance, value: current}) = queue.pop() {
            if memo[current] == distance {
                for &Path{to: next, cost: length} in &points[current] {
                    if memo[next] > distance + length {
                        memo[next] = distance + length;
                        queue.push(ValueWithKey{key: distance + length, value: next});
                    }
                }
            }
        }
        let mut max = 0_f64;
        for i in 0 .. 2 * n{
            if max < memo[i] {
                max = memo[i];
            }
        }
        for i in 0 .. n {
            for j in 1 .. cross[i].len() - 1 {
                let distance = cross[i][j - 1].key - cross[i][j].key;
                if max < min_f64(memo[cross[i][j - 1].value], memo[cross[i][j].value]) + distance / 2_f64 {
                    max = min_f64(memo[cross[i][j - 1].value], memo[cross[i][j].value]) + distance / 2_f64;
                }
            }
        }
        println!("{:.*}", 10, max);
    }
}