Go: package main

import (
	"container/heap"
	"fmt"
)

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
}

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)
		}
		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)
		start := Node{NowPosition: s, DiscountTicketTCount: c, Amount: 0}
		heap.Push(&pq, &start)
		for len(pq) != 0 {
			now := heap.Pop(&pq).(*Node)
			if now.NowPosition == d {
				fmt.Println(now.Amount)
				break
			}
			for _, v := range pointMap[now.NowPosition] {
				next := &Node{v.NextPoint, now.DiscountTicketTCount, now.Amount + v.Fee}
				heap.Push(&pq, next)
				if now.DiscountTicketTCount > 0 {
					next = &Node{v.NextPoint, now.DiscountTicketTCount - 1, now.Amount + v.Fee/2}
					heap.Push(&pq, next)
				}
			}
		}
	}
}

C++: #include <cstdio>
#include <utility>
#include <cctype>
#include <vector>
#include <algorithm>
#include <queue>
#include <climits>
using namespace std;

#ifdef __linux
#define _U(s) s##_unlocked
#else
#define _U(s) _##s##_nolock
#define _CRT_DISABLE_PERFCRIT_LOCKS
#endif
#define gcu _U(getchar)
#define pcu _U(putchar)
#define _DEF(r, n, ...) inline r n(__VA_ARGS__) noexcept
#define _T template <typename T>
#define _HT template <typename H,typename... T>
#define _OP(t) inline operator t()
struct _in {
#ifdef _GLIBCXX_STRING
	_OP(string){string s;char c;while(isspace(c = gcu()));do{s+=c;}while(c=gcu(),c!=' '&&c!='\n'&&c!=EOF);return s;}
#define _S
#endif
	_OP(char){char c=gcu();gcu();return c;}
	_OP(double){double d; scanf("%lf",&d); gcu();return d;}
	_T _OP(T){T n{},m{1},c;while(isspace(c = gcu()));if(c=='-')m=-1,c=gcu();do{n=10*n+(c-'0'),c=gcu();}while(c>='0'&&c<='9');return m*n;}
} in;
#define _SCAN(...) _DEF(bool,scan,__VA_ARGS__)
#ifdef _S
_SCAN(string &o) {int c{gcu()};if(c==EOF)return false;else{ungetc(c,stdin);string t=move(in);o=t;return true;}}
#endif
_T _SCAN(T &o) {int c{gcu()};return c==EOF?false:(ungetc(c,stdin),o=in,true);}
_HT _SCAN(H &h,T&&... t){return scan(h)&&scan(t...);}
#define _OUT(...) _DEF(void,out,__VA_ARGS__)
#define _OUTL(...) _DEF(void,outl,__VA_ARGS__)
_OUT(bool b){pcu('0'+b);}
_OUT(const char *s){while(*s)pcu(*s++);}
_OUT(char c){pcu(c);}
#ifdef _S
_OUT(string &s){for(char c:s)pcu(c);}
#endif
_T _OUT(T n){static char b[20];char *p=b;T m=n<0?pcu('-'),-1:1;
	if(!n)*p++='0';else while(n)*p++=(char)(n%10*m+'0'),n/=10;while(p!=b)pcu(*--p);}
_OUTL(){out('\n');}
#ifdef _GLIBCXX_VECTOR
	_T _OUT(vector<T> &v){for(T &x:v)out(&x == &v[0]?"":" "),out(x);}
#endif
	_HT _OUT(H &&h, T... t){out(h);out(t...);}
	template <typename... T> _OUTL(T... t){out(t...);outl();}
	struct range{
		int e,b=0,s=1;range(int _b,int _e,int _s):e(_e),b(_b),s(_s){} range(int _b,int _e): e(_e), b(_b){} range(int _e):e(_e){}
		struct it{int v,s; it(int _v,int _s):v(_v),s(_s){} operator int()const{return v;} operator int&(){return v;}int operator*()const{return v;}
			it& operator++(){v+=s;return *this;} }; it begin(){return {b,s};} it end(){return {e,s};}};
#define times(i,n) for(int i=n;i;i--)

template <typename T>
using V = vector<T>;

struct E {
	int t, c;
};

struct P {
	int c, t, k;
	bool operator < (P a) const {return c > a.c;}
};

int main() {
	for (int c, n, m, s, d; c = in, n = in, m = in, s = in, d = in;) {
		s--, d--;
		V<V<E>> v(n, V<E>());
		times(i, m) {
			int a {(int) in - 1}, b {(int) in - 1}, f {in};
			v[a].push_back({b, f});
			v[b].push_back({a, f});
		}
		V<V<int>> dp(n, V<int>(c + 1, INT_MAX / 2));
		dp[s][c] = 0;
		priority_queue<P> q;
		q.push({0, s, c});
		while (!q.empty()) {
			P t = q.top();
			q.pop();
			if (t.t == d) {
				outl(t.c);
				break;
			}
			if (dp[t.t][t.k] < t.c)
				continue;
			for (E e: v[t.t]) {
				auto f = [&](int c, int k) {
					if (dp[e.t][k] > dp[t.t][t.k] + c) {
						dp[e.t][k] = dp[t.t][t.k] + c;
						q.push({dp[e.t][k], e.t, k});
					}
				};
				if (t.k > 0)
					f(e.c / 2, t.k - 1);
				f(e.c, t.k);
			}
		}
	}
}

C++: #include <iostream>
#include <vector>
#include <queue>
#include <functional>
#include <algorithm>

constexpr int MAX_N = 100, INF = (int)1e9;
using P = std::pair<std::pair<int, int>,int>;

struct edge {
	int to_, cost_;
	edge() = default;
	edge(int to, int cost) : to_(to), cost_(cost) {}
};

int c, n;
std::vector<edge> G[MAX_N];
int d[MAX_N];

int dijkstra(int s, int g) {
	std::fill(d, d + n, INF);
	std::priority_queue<P, std::vector<P>, std::greater<P>> que;
	d[s] = 0;
	que.emplace(std::make_pair(d[s], s), c);
	while (!que.empty()) {
		P p = que.top(); que.pop();
		int v = p.first.second;
		if (v == g)
			break;
		for (int i = 0; i < G[v].size(); ++i) {
			edge e = G[v][i];
			if (p.second > 0 && d[e.to_] > d[v] + e.cost_ / 2) {
				d[e.to_] = d[v] + e.cost_ / 2;
				que.emplace(std::make_pair(d[e.to_], e.to_), p.second - 1);
			}
			if (d[e.to_] > d[v] + e.cost_) {
				d[e.to_] = d[v] + e.cost_;
				que.emplace(std::make_pair(d[e.to_], e.to_), p.second);
			}
		}
	}
	return d[g];
}

int main() {
	int m, s, g;
	while (1) {
		std::cin >> c >> n >> m >> s >> g;
		if (c + n + m + s + g == 0)
			break;
		for (int i = 0; i < n; ++i)
			G[i].clear();
		--s;
		--g;
		int a, b, f;
		for (int i = 0; i < m; ++i) {
			std::cin >> a >> b >> f;
			--a;
			--b;
			G[a].push_back(edge(b, f));
			G[b].push_back(edge(a, f));
		}
		std::cout << dijkstra(s, g) << std::endl;
	}
	return 0;
}

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

class edge{
	public:
		int to,cost;
		edge();
		edge(int _to,int _cost){
			to = _to;
			cost = _cost;
		}
};
class state{
	public:
		int id,cost,ticket;
		state();
		state(int _id,int _cost,int _ticket){
			id = _id;
			cost = _cost;
			ticket = _ticket;
		}
		bool operator<(const state st)const{
			return cost > st.cost;
		}
};
const int INF = 1000000000;

int main()
{
	int c,n,m,s,g;
	while(cin >> c >> n >> m >> s >> g){
		if(!c&&!n&&!m&&!s&&!g)
			break;
		vector<edge> t[101];
		int d[101][11];
		for(int i=0;i<m;i++){
			int a,b,cost;
			cin >> a >> b >> cost;
			a--;b--;
			t[a].push_back(edge(b,cost));
			t[b].push_back(edge(a,cost));
		}
		s--;g--;

		int ans = INF;
		for(int i=0;i<11;i++){
			fill(d[i],d[i]+100,INF);
		}
		d[s][c] = 0;
		priority_queue<state> que;
		que.push(state(s,0,c));
		while(!que.empty()){
			state st = que.top();
			que.pop();
			int v = st.id;
			if(st.id == g)
				ans = min(ans,st.cost);
			for(unsigned i=0;i<t[v].size();i++){
				edge e = t[v][i];
				
				if(d[e.to][st.ticket] > d[v][st.ticket] + e.cost){
					d[e.to][st.ticket] = d[v][st.ticket] + e.cost;
					que.push(state(e.to,d[e.to][st.ticket],st.ticket));
				}
				if(st.ticket>0){
					if(d[e.to][st.ticket-1] > d[v][st.ticket] + (e.cost)/2){
						d[e.to][st.ticket-1] = d[v][st.ticket] + (e.cost)/2;
						que.push(state(e.to,d[e.to][st.ticket-1],st.ticket-1));
					}
				}
			}
		}
		cout << ans << endl;
	}
	return 0;
}