Problem:
Score : 400 points

Problem Statement

There are N towns in the State of Atcoder, connected by M bidirectional roads.

The i-th road connects Town A_i and B_i and has a length of C_i.

Joisino is visiting R towns in the state, r_1,r_2,..,r_R (not necessarily in this order).

She will fly to the first town she visits, and fly back from the last town she visits, but for the rest of the trip she will have to travel by road.

If she visits the towns in the order that minimizes the distance traveled by road, what will that distance be?

Constraints

2≤N≤200

1≤M≤N×(N-1)/2

2≤R≤min(8,N) (min(8,N) is the smaller of 8 and N.)

r_i≠r_j (i≠j)

1≤A_i,B_i≤N, A_i≠B_i

(A_i,B_i)≠(A_j,B_j),(A_i,B_i)≠(B_j,A_j) (i≠j)

1≤C_i≤100000

Every town can be reached from every town by road.

All input values are integers.

Input

Input is given from Standard Input in the following format:

N M R
r_1 ... r_R
A_1 B_1 C_1
:
A_M B_M C_M

Output

Print the distance traveled by road if Joisino visits the towns in the order that minimizes it.

Sample Input 1

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

Sample Output 1

2

For example, if she visits the towns in the order of 1, 2, 3, the distance traveled will be 2, which is the minimum possible.

Sample Input 2

3 3 2
1 3
2 3 2
1 3 6
1 2 2

Sample Output 2

4

The shortest distance between Towns 1 and 3 is 4. Thus, whether she visits Town 1 or 3 first, the distance traveled will be 4.

Sample Input 3

4 6 3
2 3 4
1 2 4
2 3 3
4 3 1
1 4 1
4 2 2
3 1 6

Sample Output 3

3

Solution in Kotlin (1.0.0) (judge verdict: Accepted)

fun main(args: Array<String>) {
    val (N, M, R) = readLine()!!.split(" ").map { it.toInt() }
    val r = readLine()!!.split(" ").map { it.toInt() }.toIntArray()
    (0..(R-1)).forEach {
        r[it]--
    }
    val graph : Array<IntArray> = Array(N, { val array = IntArray(N); array.fill(100000000); array })
    (1..M).forEach {
        val (A, B, C) = readLine()!!.split(" ").map { it.toInt() }
        graph[A-1][B-1] = C
        graph[B-1][A-1] = C
    }

    val distance : Array<IntArray> = warshallFloyd(graph)
    val used = BooleanArray(9)
    var res = Int.MAX_VALUE
    used.fill(false)
    fun dfs( c: Int , las: Int , dist: Int ) {
        if ( c == R)
        {
            res  = Math.min(res, dist)
            return ;
        }
        (0..(R-1)).forEach { i ->
            if (!used[i]) {
                used [ i ]= true ;
                if ( las == -1) dfs ( c +1 ,i ,0);
                else dfs ( c +1 ,i , dist + distance[ r [ las ]][ r [ i ]]);
                used [ i ]= false ;
            }
        }
    }

    dfs (0 , -1 ,0);
    /*
    var min = Int.MAX_VALUE.toLong()
    fun updateMin(r: IntArray) {
        var localMin = 0L
        var lastAt = r[0]
        (1..(R-1)).forEach {
            localMin += distance[lastAt][r[it]]
            lastAt = r[it]
        }
        min = Math.min(min, localMin)
    }

    updateMin(r)
    while(findNextPermutation(r)) {
        updateMin(r)
    }
    */
    println(res)
}

fun search(c: Array<IntArray>, list: MutableList<Int>, now: Int, sum: Int): Int {
    if (list.size == 1) return sum + c[now][list[0]]
    var min = Integer.MAX_VALUE
    for (i in list.indices) {
        val next = list.removeAt(i)
        val tmp = search(c, list, next, sum + c[now][next])
        list.add(i, next)
        if (tmp < min) min = tmp
    }
    return min
}


fun swap(data: IntArray, left: Int, right: Int): IntArray {

    // Swap the data
    val temp = data[left]
    data[left] = data[right]
    data[right] = temp

    // Return the updated array
    return data
}

// Function to reverse the sub-array
// starting from left to the right
// both inclusive
fun reverse(data: IntArray, left: Int, right: Int): IntArray {
    var left = left
    var right = right

    // Reverse the sub-array
    while (left < right) {
        val temp = data[left]
        data[left++] = data[right]
        data[right--] = temp
    }

    // Return the updated array
    return data
}

// Function to find the next permutation
// of the given integer array
fun findNextPermutation(data: IntArray): Boolean {
    var data = data

    // If the given dataset is empty
    // or contains only one element
    // next_permutation is not possible
    if (data.size <= 1)
        return false

    var last = data.size - 2

    // find the longest non-increasing suffix
    // and find the pivot
    while (last >= 0) {
        if (data[last] < data[last + 1]) {
            break
        }
        last--
    }

    // If there is no increasing pair
    // there is no higher order permutation
    if (last < 0)
        return false

    var nextGreater = data.size - 1

    // Find the rightmost successor to the pivot
    for (i in data.size - 1 downTo last + 1) {
        if (data[i] > data[last]) {
            nextGreater = i
            break
        }
    }

    // Swap the successor and the pivot
    data = swap(data, nextGreater, last)

    // Reverse the suffix
    data = reverse(data, last + 1, data.size - 1)

    // Return true as the next_permutation is done
    return true
}


fun warshallFloyd(distance: Array<IntArray>): Array<IntArray> {
    val node_number = distance.size
    val min_distance = Array(node_number) { IntArray(node_number) }
    for (i in 0 until node_number) {
        for (j in 0 until node_number) {
            min_distance[i][j] = distance[i][j]
        }
    }
    for (via in 0 until node_number) {
        for (from in 0 until node_number) {
            for (to in 0 until node_number) {
                min_distance[from][to] = Math.min(min_distance[from][to], min_distance[from][via] + min_distance[via][to])
            }
        }
    }
    return min_distance
}