Problem:
青春の片道切符

太郎君は夏休みに電車で長旅をする計画を立てています。しかし高校生の身である太郎君が一ヵ月しかない夏休みで可能な限り遠くに旅をするには、出来るだけ安い行き方と出来るだけ早い行き方をそれぞれ見つけなければうまく計画が立てられません。太郎君が素敵な旅を満喫できるように、太郎君の計画の助けになるプログラムを作ってあげましょう。

線路の情報、駅の数を入力とし、問い合わせに応じて、最小金額または最短時間を出力するプログラムを作成してください。

Input

複数のデータセットの並びが入力として与えられます。入力の終わりはゼロふたつの行で示されます。各データセットは以下の形式で与えられます。

n m
a1 b1 cost1 time1
a2 b2 cost2 time2
:
an bn costn timen
k
p1 q1 r1
p2 q2 r2
:
pk qk rk

1 行目に線路の情報の数 n (1 ≤ n ≤ 3000)と駅の数 m (1 ≤ m ≤ 100) が与えられます。

続く n 行に i 番目の路線の情報が与えられます。各路線の情報として、路線がつなぐ２つの駅の番号 ai, bi (1 ≤ ai, bi ≤ m)、料金 costi (1 ≤ costi ≤ 1000)、移動時間 timei (1 ≤ timei ≤ 1000) が与えられます。ただし、各駅は 1 から m まで順番に番号が付けられているものとします。
なお、ai と bi が線路でつながっていれば、ai から bi、 bi からai の両方の移動が同じ料金と時間で可能とします。

続く行に問い合わせの数 k (1 ≤ k ≤ 200) が与えられます。続く k 行に i 番目の問い合わせが与えられます。各問合わせとして、出発駅 pi 、到着駅 qi 、出力する値の種類 ri (0 または 1)が与えられます。なお、問い合わせには必ず経路があるものとします。

データセットの数は 50 を超えない。

Output

データセットごとに、最小金額もしくは最短時間を１行に出力します。ri が 0 の時は最小金額を、 1 の時は最短時間を出力します。

Sample Input

6 5
1 2 200 10
1 4 400 15
1 3 250 25
2 4 100 10
4 5 150 20
3 5 300 20
2
1 5 0
1 5 1
0 0

Output for the Sample Input

450
35

Solution in C# (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Linq;

namespace AOJ.Volume2
{
    public class TravelingAlone
    {
        private enum Status
        {
            NotYet,
            Temporary,
            Complete,
        }

        private class Node
        {
            public int Name { get; private set; }
            public long MinValue { get; set; }
            public Status NodeStatus { get; set; }

            public Node(int n)
            {
                this.Name = n;
            }
        }

        private struct Branch
        {
            public Node Node1;
            public Node Node2;
            public int Cost;
            public int Time;
        }

        private static void UpdateNodeProperty(List<Branch> branches, Node source, int type)
        {
            Node distination;
            // sourceと隣接しているNodeを検索
            foreach (var b in branches)
            {
                if (b.Node1.Name == source.Name) { distination = b.Node2; }
                else if (b.Node2.Name == source.Name) { distination = b.Node1; }
                else { continue; }

                // 隣接Nodeが見つかった場合の処理
                // 確定Nodeは無視
                if (distination.NodeStatus == Status.Complete) { continue; }

                // NodeのMinValueを計算
                // type = 0の場合最小金額、type = 1の場合最短時間
                if (type == 0)
                {
                    distination.MinValue = Math.Min(distination.MinValue, source.MinValue + b.Cost);
                }
                else
                {
                    distination.MinValue = Math.Min(distination.MinValue, source.MinValue + b.Time);
                }
                distination.NodeStatus = Status.Temporary;
            }
        }

        public static void Main()
        {
            while (true)
            {
                var input = Console.ReadLine().Split(' ');
                int b_cnt = int.Parse(input[0]);
                int n_cnt = int.Parse(input[1]);
                if (b_cnt <= 0 && n_cnt <= 0) { break; }

                // ノード(駅)のリストを作成
                var node_list = new List<Node>();
                for (int i = 1; i <= n_cnt; i++)
                {
                    node_list.Add(new Node(i));
                }

                // ブランチ(路線情報)のリストを作成
                var branch_list = new List<Branch>();
                for (int i = 0; i < b_cnt; i++)
                {
                    input = Console.ReadLine().Trim().Split(' ');
                    var node_a = node_list.First(x => x.Name == int.Parse(input[0]));
                    var node_b = node_list.First(x => x.Name == int.Parse(input[1]));
                    var b = new Branch();
                    b.Node1 = node_a;
                    b.Node2 = node_b;
                    b.Cost = int.Parse(input[2]);
                    b.Time = int.Parse(input[3]);
                    branch_list.Add(b);
                }

                // 問い合わせの数を取得
                int query = int.Parse(Console.ReadLine());

                for (int i = 0; i < query; i++)
                {
                    input = Console.ReadLine().Trim().Split(' ');
                    int type = int.Parse(input[2]);
                    if (input[0] == input[1])
                    {
                        Console.WriteLine("0");
                        continue;
                    }

                    // ノードを初期化
                    node_list.ForEach(x =>
                        {
                            x.MinValue = long.MaxValue;
                            x.NodeStatus = Status.NotYet;
                        });

                    // ダイクストラ法で最小値を求める
                    var start_node = node_list.First(x => x.Name == int.Parse(input[0]));
                    var end_node = node_list.First(x => x.Name == int.Parse(input[1]));
                    start_node.MinValue = 0;
                    start_node.NodeStatus = Status.Complete;

                    var scan_node = start_node;
                    while (scan_node != null)
                    {
                        // 隣接ノードの最小値を計算
                        UpdateNodeProperty(branch_list, scan_node, type);
                        // 未確定の中で最小値を持つノードを検索
                        if (node_list.Count(x => x.NodeStatus == Status.Temporary) == 0) { scan_node = null; }
                        else
                        {
                            long min_val = node_list.Where(x => x.NodeStatus == Status.Temporary).Min(y => y.MinValue);
                            scan_node = node_list.FirstOrDefault(x => x.MinValue == min_val);
                            scan_node.NodeStatus = Status.Complete;
                        }
                        if (end_node.NodeStatus == Status.Complete) { break; }
                    }
                    Console.WriteLine(end_node.MinValue);
                }
            }
        }
    }
}