Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Problem F:
Rabbit Jumping

There are $K$ rabbits playing on rocks floating in a river. They got tired of playing on the rocks on which they are standing currently, and they decided to move to other rocks. This seemed an easy task initially, but there are so many constraints that they got totally confused.

First of all, by one leap, they can only move to a rock within $R$ meters from the current rock. Also, they can never leap over rocks. That is, when they leap in some direction, they should land on the nearest rock in that direction. Furthermore, since they always want to show off that they are courageous, they will never leap to rocks downriver. Finally, since they never want to admit they have been defeated, they never land on a rock if the rock is already visited by other rabbits.

In this situation, is it possible for them to move to their destination rocks? If possible, please minimize the sum of their moving distance.

Input

The first line contains two integers $N$ ($1 \leq N \leq 100$), $K$ ($1 \leq K \leq 3$) and a real number $R$ ($0 \leq R \leq 10^4$), which denote the number of rocks, the number of rabbits, and the maximum distance a rabbit can leap, respectively. The second line contains $K$ numbers $s_1, ..., s_K$ where $s_i$ denote the rock where the $i$-th rabbit is standing. Similarly, the third line contains $K$ numbers $t_1, ..., t_K$ where $t_i$ denote the destination rock for the $i$-th rabbit. $s_1, ..., s_K$ are distinct, and $t_1, ..., t_K$ are distinct. A destination rock of a rabbit is always different from the rock he/she is standing currently.

Then the following $N$ lines describe the positions of the rocks. The $i$-th line in this block contains two integers $x_i$ and $y_i$ ($0 \leq x_i, y_i \leq 10,000$), which indicate the coordinates of the $i$-th rock. The river flows along Y-axis, toward the direction where Y-coordinate decreases. No pair of rocks has identical coordinates.

You may assume that the answer do not change even if you increase $R$ by up to $10^{-5}$.

Output

If all the rabbits can move to their destination rocks, print the minimum total distance they need to leap. If not, print "-1" (without quotes). Your answer may contain at most $10^{-6}$ of absolute error.

Sample Input

6 3 1.0
1 2 3
4 5 6
0 0
1 0
2 0
0 1
1 1
2 1

Output for the Sample Input

3

Solution in C# (judge verdict: Accepted)

using System;
using System.Linq;
using System.Collections.Generic;
//using System.Numerics;
using Debug = System.Diagnostics.Debug;
using SB = System.Text.StringBuilder;
using Number = System.Int64;
namespace Program {
    public class Solver {
        public void Solve() {
            var n = ri;
            var kk = ri;
            var D = rd;
            var s = Enumerate(3, x => n + x);
            var t = Enumerate(3, x => n + x);
            for (int i = 0; i < kk; i++)
                s[i] = ri - 1;
            for (int i = 0; i < kk; i++)
                t[i] = ri - 1;
            var XY = Enumerate(n + 5, x => new int[] { 1000000, 1000000 });
            for (int i = 0; i < n; i++)
                XY[i] = new int[] { ri, ri };
            var P = Enumerate(10050, x => new List<int>());
            for (int i = 0; i < n; i++)
                P[XY[i][1]].Add(i);
            for (int i = 0; i < 10050; i++)
                P[i].Sort((l, r) => XY[l][0].CompareTo(XY[r][0]));
            var g = Enumerate(n, x => new int[n]);
            var dist = Enumerate(n, x => new double[n]);
            for (int i = 0; i < n; i++)
                for (int j = i + 1; j < n; j++) {
                    var dx = XY[j][0] - XY[i][0];
                    var dy = XY[j][1] - XY[i][1];
                    g[i][j] = g[j][i] = dx * dx + dy * dy;
                    dist[i][j] = dist[j][i] = Math.Sqrt(g[i][j]);
                }
            var go = Enumerate(n, x => new bool[n]);
            for (int i = 0; i < n; i++)
                for (int j = i + 1; j < n; j++) {
                    //i = 0; j = 51;
                    var d = dist[i][j];
                    if (D < d) continue;
                    go[i][j] = true;
                    for (int k = 0; k < n; k++) {
                        if (k == i || k == j) continue;
                        var e = dist[i][k] + dist[k][j];
                        if (Math.Abs(d - e) <= 1e-9)
                            go[i][j] = false;
                    }
                    go[j][i] = go[i][j];
                }

            var dp = new double[n + 5, n + 5, n + 5];
            for (int i = 0; i < n + 5; i++)
                for (int j = 0; j < n + 5; j++)
                    for (int k = 0; k < n + 5; k++)
                        dp[i, j, k] = 1e18;
            dp[s[0], s[1], s[2]] = 0;

            for (int py = 0; py < 10050; py++) {
                //go right,go left, go up
                for (int k = 0; k < 3; k++) {
                    for (int i = 0; i < P[py].Count; i++) {
                        var x = P[py][i];
                        for (int y = 0; y < n + 5; y++)
                            for (int z = 0; z < n + 5; z++) {
                                if (y == z) continue;
                                if (XY[y][1] < py) continue;
                                if (XY[z][1] < py) continue;
                                if (x == t[0]) update(ref dp[n, y, z], dp[x, y, z]);
                                if (x == t[1]) update(ref dp[y, n + 1, z], dp[y, x, z]);
                                if (x == t[2]) update(ref dp[y, z, n + 2], dp[y, z, x]);
                                if (k != 2 && i + 1 < P[py].Count) {
                                    var nx = P[py][i + 1];
                                    if (nx != y && nx != z) {
                                        update(ref dp[nx, y, z], dp[x, y, z] + dist[x][nx]);
                                        update(ref dp[y, nx, z], dp[y, x, z] + dist[x][nx]);
                                        update(ref dp[y, z, nx], dp[y, z, x] + dist[x][nx]);
                                    }
                                }
                                if (k == 2) {
                                    for (int nx = 0; nx < n; nx++) {
                                        if (nx == y || nx == z) continue;
                                        if (XY[nx][1] <= py) continue;
                                        if (!go[x][nx]) continue;
                                        update(ref dp[nx, y, z], dp[x, y, z] + dist[x][nx]);
                                        update(ref dp[y, nx, z], dp[y, x, z] + dist[x][nx]);
                                        update(ref dp[y, z, nx], dp[y, z, x] + dist[x][nx]);
                                    }
                                }

                            }
                    }
                    P[py].Reverse();
                }
            }
            var ans = dp[n, n + 1, n + 2];
            if (ans >= 1e+17) ans = -1;
            Console.WriteLine(ans);
        }
        void update(ref double x, double y) {
            if (y >= 1e17) return;
            if (x > y)
                x = y;
        }
        const long INF = 1L << 60;
        //int[] dx = { -1, 0, 1, 0 };
        //int[] dy = { 0, 1, 0, -1 };

        int ri { get { return sc.Integer(); } }
        long rl { get { return sc.Long(); } }
        double rd { get { return sc.Double(); } }
        string rs { get { return sc.Scan(); } }
        public IO.StreamScanner sc = new IO.StreamScanner(Console.OpenStandardInput());

        static T[] Enumerate<T>(int n, Func<int, T> f) {
            var a = new T[n];
            for (int i = 0; i < n; ++i) a[i] = f(i);
            return a;
        }

        static public void Swap<T>(ref T a, ref T b) {
            var tmp = a;
            a = b;
            b = tmp;
        }
    }
}

#region main

static class Ex {
    static public string AsString(this IEnumerable<char> ie) {
        return new string(ie.ToArray());
    }

    static public string AsJoinedString<T>(this IEnumerable<T> ie, string st = " ") {
        return string.Join(st, ie.Select(x => x.ToString()).ToArray());
        //return string.Join(st, ie);
    }

    static public void Main() {
        Console.SetOut(new Program.IO.Printer(Console.OpenStandardOutput()) { AutoFlush = false });
        var solver = new Program.Solver();
        solver.Solve();
        Console.Out.Flush();
    }
}

#endregion
#region Ex

namespace Program.IO {
    using System.IO;
    using System.Text;
    using System.Globalization;

    public class Printer: StreamWriter {
        public override IFormatProvider FormatProvider {
            get { return CultureInfo.InvariantCulture; }
        }
        public Printer(Stream stream) : base(stream, new UTF8Encoding(false, true)) { }
    }

    public class StreamScanner {
        public StreamScanner(Stream stream) {
            str = stream;
        }

        public readonly Stream str;
        private readonly byte[] buf = new byte[1024];
        private int len, ptr;
        public bool isEof = false;
        public bool IsEndOfStream {
            get { return isEof; }
        }

        private byte read() {
            if (isEof) return 0;
            if (ptr >= len) {
                ptr = 0;
                if ((len = str.Read(buf, 0, 1024)) <= 0) {
                    isEof = true;
                    return 0;
                }
            }
            return buf[ptr++];
        }

        public char Char() {
            byte b = 0;
            do b = read(); while ((b < 33 || 126 < b) && !isEof);
            return (char)b;
        }

        public string Scan() {
            var sb = new StringBuilder();
            for (var b = Char(); b >= 33 && b <= 126; b = (char)read()) sb.Append(b);
            return sb.ToString();
        }

        public string ScanLine() {
            var sb = new StringBuilder();
            for (var b = Char(); b != '\n' && b != 0; b = (char)read()) if (b != '\r') sb.Append(b);
            return sb.ToString();
        }

        public long Long() {
            return isEof ? long.MinValue : long.Parse(Scan());
        }

        public int Integer() {
            return isEof ? int.MinValue : int.Parse(Scan());
        }

        public double Double() {
            return isEof ? double.NaN : double.Parse(Scan(), CultureInfo.InvariantCulture);
        }
    }
}

#endregion