Go: package main

import (
	"container/heap"
	"fmt"
	"runtime"
)

type Node struct {
	NowPosition          int
	DiscountTicketTCount int
	Amount               int
}

type PriorityQueueNode []*Node

func (pq PriorityQueueNode) Len() int {
	return len(pq)
}

func (pq PriorityQueueNode) Less(i, j int) bool {
	return pq[i].Amount < pq[j].Amount
}

func (pq PriorityQueueNode) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
}

func (pq *PriorityQueueNode) Push(node interface{}) {
	*pq = append(*pq, node.(*Node))
}

func (pq *PriorityQueueNode) Pop() interface{} {
	old := *pq
	n := len(old)
	item := old[n-1]
	*pq = old[0 : n-1]
	return item
}

type Point struct {
	NextPoint int
	Fee       int
}

type Memo struct {
	NowPoint             int
	DiscountTicketTCount int
}

func main() {
	var c, n, m, s, d int
	var a, b, f int

	for {
		fmt.Scan(&c, &n, &m, &s, &d)
		if c == 0 && n == 0 && m == 0 && s == 0 && d == 0 {
			break
		}
		s--
		d--
		pointMap := make([][]Point, n)
		for i := 0; i < n; i++ {
			pointMap[i] = make([]Point, 0, n)
		}
		for i := 0; i < m; i++ {
			fmt.Scan(&a, &b, &f)
			a--
			b--
			pointMap[a] = append(pointMap[a], Point{NextPoint: b, Fee: f})
			pointMap[b] = append(pointMap[b], Point{NextPoint: a, Fee: f})
		}
		pq := make(PriorityQueueNode, 0, m)
		start := Node{NowPosition: s, DiscountTicketTCount: c, Amount: 0}
		heap.Push(&pq, &start)
		memo := make(map[Memo]int)
		for len(pq) != 0 {
			now := heap.Pop(&pq).(*Node)
			if now.NowPosition == d {
				fmt.Println(now.Amount)
				break
			}
			memo[Memo{NowPoint: now.NowPosition, DiscountTicketTCount: now.DiscountTicketTCount}] = now.Amount
			for _, v := range pointMap[now.NowPosition] {
				next := &Node{v.NextPoint, now.DiscountTicketTCount, now.Amount + v.Fee}
				if memoAmount, ok := memo[Memo{NowPoint: v.NextPoint, DiscountTicketTCount: now.DiscountTicketTCount}]; !ok || (ok && memoAmount > next.Amount) {
					memo[Memo{NowPoint: v.NextPoint, DiscountTicketTCount: now.DiscountTicketTCount}] = next.Amount
					heap.Push(&pq, next)
				}
				if now.DiscountTicketTCount > 0 {
					next = &Node{v.NextPoint, now.DiscountTicketTCount - 1, now.Amount + v.Fee/2}
					if memoAmount, ok := memo[Memo{NowPoint: v.NextPoint, DiscountTicketTCount: now.DiscountTicketTCount}]; !ok || (ok && memoAmount > next.Amount) {
						memo[Memo{NowPoint: v.NextPoint, DiscountTicketTCount: now.DiscountTicketTCount}] = next.Amount
						heap.Push(&pq, next)
					}
				}
			}
		}
		runtime.GC()
	}
}

C++: #include <cstdio> 
#include <algorithm> 
#include <queue> 
 
using namespace std; 
 
const int INF   = 100000000; 
const int C_MAX = 10; 
const int N_MAX = 100; 
 
// ¬Ìîñ 
// pair<cèÌø, ¬ÌÔ> 
typedef pair<int, int> T; 
 
// n_Ìîñ 
// pair<Å¬RXg, n_Ìîñ> 
typedef pair<int, T> P; 
 
// üÍ 
int c, n, m, s, d; 
 
// »Ì¬ÜÅÌÅ¬ÌRXg 
// cost[¬ÌÔ][cèÌø] = ïp 
int cost[N_MAX][C_MAX + 1]; 
 
// ùÉÅKlªèÏÝ©Ç¤© 
bool flag[N_MAX][C_MAX + 1]; 
 
// HüÌîñ 
// line[n_][I_] = ¿à 
int line[N_MAX][N_MAX]; 
 
// DP pL[ 
typedef priority_queue<P, vector<P>, greater<P> > Q; 
Q dp_q; 
 
// _CNXg@ 
int dijkstra(){ 
     
    while(!dp_q.empty()){ 
        P  p = dp_q.top(); dp_q.pop(); 
        T &t = p.second; 
         
        // ùÉÅKlªèÏÝ©²×é 
        if(flag[t.second][t.first]) continue; 
        flag[t.second][t.first] = true; 
         
        // ÅIn_ 
        if(t.second == d){ 
            return p.first; 
        } 
         
        for(int i = 0; i < n; ++i){ 
            // øðgíÈ¢ê 
            if(cost[i][t.first] > p.first + line[t.second][i]){ 
                cost[i][t.first] = p.first + line[t.second][i]; 
                dp_q.push(P(p.first + line[t.second][i], T(t.first, i))); 
            } 
             
            // øðg¤ê 
            if(t.first > 0 && cost[i][t.first - 1] > p.first + line[t.second][i] / 2){ 
                cost[i][t.first - 1] = p.first + line[t.second][i] / 2; 
                dp_q.push(P(p.first + line[t.second][i] / 2, T(t.first - 1, i))); 
            } 
        } 
    } 
     
    return INF; 
} 
 
void solve(){ 
     
    // ú» 
    for(int i = 0; i < N_MAX; ++i){ 
        for(int j = 0; j < C_MAX + 1; ++j){ 
            cost[i][j] = INF; 
            flag[i][j] = false; 
        } 
    } 
     
    // Jnn_ 
    dp_q = Q(); 
    dp_q.push(P(0, T(c, s))); 
     
    // _CNXg@ 
    printf("%d\n", dijkstra()); 
} 
 
int main(){ 
    int a, b, f; 
     
    while(scanf("%d %d %d %d %d", &c, &n, &m, &s, &d), c > 0){ 
        --s; 
        --d; 
         
        // ú» 
        for(int i = 0; i < N_MAX; ++i){ 
            for(int j = 0; j < N_MAX; ++j){ 
                line[i][j] = INF; 
            } 
        } 
         
        for(int i = 0; i < m; ++i){ 
            scanf("%d %d %d", &a, &b, &f); 
             
            --a; 
            --b; 
             
            line[a][b] = f; 
            line[b][a] = f; 
        } 
         
        solve(); 
    } 
     
    return 0; 
}

C++: #include<iostream>
#include<map>
#include<queue>
#include<vector>
using namespace std;

#define N 104
#define C 53
#define INF 1000000007
#define rep(i, n) for(int i=0; i<n; ++i)

struct Edge {
	int to, cost;
};

typedef pair<int, int> P;
typedef pair<int, P> IP;

typedef vector<Edge> Graph;

Graph g[N];

int dist[N][C];
int n, c;
int dijkstra(int s, int t) {
	priority_queue<IP, vector<IP>, greater<IP> > q;
	rep(i, n) rep(j, c+1) dist[i][j] = INF;
	dist[s][0] = 0;
	q.push(IP(0, P(s, 0)));
	while(!q.empty()) {
		int cost = q.top().first, u = q.top().second.first;
		int p = q.top().second.second; q.pop();
		if(dist[u][p] < cost) continue;
		rep(i, g[u].size()) {
			Edge &e = g[u][i];
			if(dist[u][p] + e.cost < dist[e.to][p]) {
				dist[e.to][p] = dist[u][p] + e.cost;
				q.push(IP(dist[e.to][p], P(e.to, p)));
			}
			if(p < c && dist[u][p] + (e.cost / 2) < dist[e.to][p+1]) {
				dist[e.to][p+1] = dist[u][p] + (e.cost / 2);
				q.push(IP(dist[e.to][p+1], P(e.to, p+1)));
			}
		}
	}
	return dist[t][c];
}


int main() {
	int m, s, d;
	while(cin >> c >> n >> m >> s >> d && c && n && m && s && d) {
		--s; --d;
		rep(i, n) g[i].clear();
		rep(i, m) {
			int a, b, f;
			cin >> a >> b >> f; --a; --b;
			g[a].push_back((Edge){b, f});
			g[b].push_back((Edge){a, f});
		}
		cout << dijkstra(s, d) << endl;
	}
	return 0;
}