Problem:
Traveling Salesman Problem

For a given weighted directed graph G(V, E), find the distance of the shortest route that meets the following criteria:

It is a closed cycle where it ends at the same point it starts.

It visits each vertex exactly once.

Input

|V| |E|
s0 t0 d0
s1 t1 d1
:
s|E|-1 t|E|-1 d|E|-1

|V| is the number of vertices and |E| is the number of edges in the graph. The graph vertices are named with the numbers 0, 1,..., |V|-1 respectively.

si and ti represent source and target vertices of i-th edge (directed) and di represents the distance between si and ti (the i-th edge).

Output

Print the shortest distance in a line. If there is no solution, print -1.

Constraints

2 ≤ |V| ≤ 15

0 ≤ di ≤ 1,000

There are no multiedge

Sample Input 1

4 6
0 1 2
1 2 3
1 3 9
2 0 1
2 3 6
3 2 4

Sample Output 1

16

Sample Input 2

3 3
0 1 1
1 2 1
0 2 1

Sample Output 2

-1

Solution in JAVA (judge verdict: Accepted)

import java.util.Map.Entry;
import java.io.*;
import java.util.*;

public class Main {
	
	static int[][] dp;
	static int N;
	static int[][] graph;
	static int INF = 16000;
	
	public static void main(String[] args) throws IOException {
		FastScanner sc = new FastScanner(System.in);
		
		N = sc.nextInt();
		int M = sc.nextInt();
		graph = new int[N][N];
		for(int i = 0; i < N; i++) Arrays.fill(graph[i], INF);
		for(int i = 0; i < M; i++){
			int s = sc.nextInt();
			int t = sc.nextInt();
			int d = sc.nextInt();
			graph[s][t] = d;
		}
		
		dp = new int[1 << N][N];
		for(int i = 0; i < 1 << N; i++) Arrays.fill(dp[i], -1);
		//どこからスタートしても1周分のコストは変わらない
		dp[(1 << N) - 1][0] = 0;
		
		int ans = solve(0, 0);
		if(ans == INF)
			System.out.println(-1);
		else
			System.out.println(ans);
	}
	
	public static int solve(int S, int v){
		if(dp[S][v] != -1) return dp[S][v];
		
		int d = INF;
		for(int i = 0; i < N; i++){
			if(((S >> i) & 1) == 0 && graph[v][i] != INF){
				d = Math.min(d, solve((S | 1 << i), i) + graph[v][i]);
			}
		}
		
		dp[S][v] = d;
		
		return dp[S][v];
	}
}

class Pair{
	int to;
	int dist;
	public Pair(int t, int d){
		to = t;
		dist = d;
	}
}

class FastScanner {
    private InputStream in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    public FastScanner(InputStream in) {
		this.in = in;
	}
    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }
    private int readByte() {
    	if (hasNextByte()) return buffer[ptr++];
    	else return -1;
    }
    private static boolean isPrintableChar(int c){
    	return 33 <= c && c <= 126;
    }
    public boolean hasNext() {
    	while(hasNextByte() && !isPrintableChar(buffer[ptr]))
    		ptr++; return hasNextByte();
    }
    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }
    public long nextLong() {
        if (!hasNext()) throw new NoSuchElementException();
        long n = 0;
        boolean minus = false;
        int b = readByte();
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        if (b < '0' || '9' < b) {
            throw new NumberFormatException();
        }
        while(true){
            if ('0' <= b && b <= '9') {
                n *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return minus ? -n : n;
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
    public int nextInt() {
        long nl = nextLong();
        if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE) throw new NumberFormatException();
        return (int) nl;
    }
    public double nextDouble() {
    	return Double.parseDouble(next());
    }
}