Problem:
Chinese Postman Problem

For a given weighted undirected 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.

The route must go through every edge at least once.

Input

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

, where |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 verticess of i-th edge (undirected) and di represents the distance between si and ti (the i-th edge).

Note that there can be multiple edges between a pair of vertices.

Output

Print the shortest distance in a line.

Constraints

2 ≤ |V| ≤ 15

0 ≤ |E| ≤ 1,000

0 ≤ di ≤ 1,000

si ≠ ti

The graph is connected

Sample Input 1

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

Sample Output 1

10

Sample Input 2

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

Sample Output 2

18

Sample Input 3

2 3
0 1 1
0 1 2
0 1 3

Sample Output 3

7

Solution in C# (judge verdict: Accepted)

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

namespace DPL2_B
{
    class Program
    {
        const int INF = 1 << 30;
        const int MAX = 15;
        //???????????°
        static int n;
        //??¨??????????????????
        static int[,] d = new int[MAX,MAX];
        //??????????¬???°
        static int[] deg = new int[MAX];
        //?????????
        static int weight;
        //?\??????????????????????
        static List<int> odds = new List<int>();

        static void floyd()
        {
            var a = scan;
            n = a[0];
            int e = a[1];
            for (int i = 0; i < n; i++)            
                for (int j = 0; j < n; j++)           
                    d[i, j] = i == j ? 0 : INF;
                         
            for (int i = 0; i < e; i++)
            {
                var f = scan;
                weight += f[2];
                deg[f[0]]++;
                deg[f[1]]++;
                if (f[2] < d[f[0],f[1]])
                {
                    d[f[0], f[1]] = f[2];
                    d[f[1], f[0]] = f[2];
                }
            }
            for (int k = 0; k < n; k++)
            {
                for (int i = 0; i < n; i++)
                {
                    if (d[i, k] == INF) continue;
                    for (int j = 0; j < n; j++)
                    {
                        if (d[k, j] == INF) continue;
                        d[i, j] = Math.Min(d[i, j], d[i, k] + d[k, j]);
                    }
                }
            }
            for (int i = 0; i < n; i++) if ((deg[i] & 1) == 1) odds.Add(i);    
        }
        static void Main(string[] args)
        {
            floyd();
            int cnt = odds.Count;
            int N = 1 << cnt;
            var dp = Enumerable.Repeat(INF, N).ToArray();
            dp[0] = 0;

            //???????????????S???1????????????
            for (int S = 0; S < N; S++)
            {
                for (int i = 0; i < cnt; i++)
                {
                    if ((S & 1 << i) != 0) continue;
                    for (int j = i+1; j < cnt; j++)
                    {
                        if ((S & 1 << j) != 0) continue;
                        dp[S | 1 << i | 1 << j] = Math.Min(dp[S | 1 << i | 1 << j], dp[S] + d[odds[i], odds[j]]);                     
                    }
                }
            }
            Console.WriteLine(weight + dp[N - 1]);
        }

        static int[] scan
        {
            get { return Console.ReadLine().Split().Select(int.Parse).ToArray(); }
        }
    }
}