Go: package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
	"strings"
)

var scanner = bufio.NewScanner(os.Stdin)

const INF = 0x7FFFFFFF

var pass [][]int

func main() {
	for scanner.Scan() {
		pass = make([][]int, 200)
		for i := range pass {
			pass[i] = make([]int, 200)
		}
		buf := strings.Split(scanner.Text(), " ")
		c, _ := strconv.Atoi(buf[0])
		n, _ := strconv.Atoi(buf[1])
		m, _ := strconv.Atoi(buf[2])
		s, _ := strconv.Atoi(buf[3])
		d, _ := strconv.Atoi(buf[4])
		if c == 0 && n == 0 && m == 0 && s == 0 && d == 0 {
			break
		}
		s--
		d--
		for i := 0; i < 200; i++ {
			for j := 0; j < 200; j++ {
				pass[i][j] = INF
			}
		}
		for i := 0; i < 200; i++ {
			pass[i][i] = 0
		}
		for i := 0; i < m; i++ {
			scanner.Scan()
			buf_ := strings.Split(scanner.Text(), " ")
			a, _ := strconv.Atoi(buf_[0])
			b, _ := strconv.Atoi(buf_[1])
			f, _ := strconv.Atoi(buf_[2])
			a--
			b--
			pass[a][b] = f
			pass[b][a] = f
		}
		fmt.Println(dijkstra(s, d, c, n))
	}
}

func dijkstra(s, g, c, n int) float64 {
	d := make([][]float64, 200)
	used := make([][]bool, 200)
	for i := 0; i < 200; i++ {
		d[i] = make([]float64, 20)
		used[i] = make([]bool, 20)
	}
	for i := range d {
		for j := range d[i] {
			d[i][j] = INF
		}
	}
	d[s][c] = 0
	for {
		v := -1
		w := -1
		for u := 0; u < n; u++ {
			for i := 0; i < c+1; i++ {
				if !used[u][i] && (v == -1 || d[u][i] < d[v][w]) {
					v = u
					w = i
				}
			}
		}
		if v == -1 {
			break
		}
		used[v][w] = true
		for u := 0; u < n; u++ {
			d[u][w] = math.Min(d[u][w], d[v][w]+float64(pass[v][u]))
			if w-1 >= 0 && pass[v][u] != INF {
				d[u][w-1] = math.Min(d[u][w-1], d[v][w]+(float64(pass[v][u]/2.0)))
			}
		}
	}
	ret := float64(INF)
	for i := 0; i < c+1; i++ {
		ret = math.Min(ret, d[g][i])
	}
	return ret
}

C++: #include<bits/stdc++.h>
using namespace std;

typedef long long int ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pair<int, int> > vii;
#define rrep(i, m, n) for(int (i)=(m); (i)<(n);  (i)++)
#define erep(i, m, n) for(int (i)=(m); (i)<=(n); (i)++)
#define  rep(i, n)    for(int (i)=0; (i)<(n);  (i)++)
#define rrev(i, m, n) for(int (i)=(n)-1; (i)>=(m); (i)--)
#define erev(i, m, n) for(int (i)=(n); (i)>=(m); (i)--)
#define  rev(i, n)    for(int (i)=(n)-1; (i)>=0; (i)--)
#define vrep(i, c)    for(__typeof((c).begin())i=(c).begin(); i!=(c).end(); i++)
#define  ALL(v)       (v).begin(), (v).end()
#define pb            push_back
template<class T, class S> inline pair<T, S> mp(const T x, const S y){ return make_pair(x, y); }
template<class T, class S> inline bool minup(T& m, const S x){ return m>(T)x ? (m=(T)x, true) : false; }
template<class T, class S> inline bool maxup(T& m, const S x){ return m<(T)x ? (m=(T)x, true) : false; }

static const int    INF = 1000000000;
static const ll     MOD = 1000000007LL;
static const double EPS = 1E-10;

const int MAX_N = 111;
const int MAX_C = 22;
int c, n, m, s, d;
int t, u, f;
struct Edge{int from, to, cost;};
vector<Edge> g[MAX_N];
int l[MAX_N][MAX_C];

int main()
{
  while(cin >> c >> n >> m >> s >> d, c){
    rep(i, n) g[i].clear();
    rep(i, MAX_N) rep(j, MAX_C) l[i][j] = INF;

    rep(i, m){
      cin >> t >> u >> f;
      g[t - 1].pb((Edge){t - 1, u - 1, f});
      g[u - 1].pb((Edge){u - 1, t - 1, f});
    }

    priority_queue<vi, vector<vi>, greater<vi> > que;
    vi tmp(3);
    tmp[0] = 0;       // ?????¢
    tmp[1] = c;       // ?????°
    tmp[2] = s -  1;  // ??´???
    l[s - 1][c] = 0;
    que.push(tmp);
    while(!que.empty()){
      vi p = que.top();  que.pop();
      int ti = p[1];
      int v = p[2];
      if(l[v][ti] < p[0]) continue;

      vrep(w, g[v]){
        Edge& e = *w;
        if(l[e.to][ti] > l[v][ti] + e.cost){
          l[e.to][ti] = l[v][ti] + e.cost;
          tmp[0] = l[e.to][ti];
          tmp[1] = ti;
          tmp[2] = e.to;
          que.push(tmp);
        }
      }

      if(c > 0) vrep(w, g[v]){
          Edge& e = *w;
          if(l[e.to][ti - 1] > l[v][ti] + e.cost / 2){
            l[e.to][ti - 1] = l[v][ti] + e.cost / 2;
            tmp[0] = l[e.to][ti - 1];
            tmp[1] = ti - 1;
            tmp[2] = e.to;
            que.push(tmp);
          }
        }
    }

    cout << l[d - 1][0] << endl;
  }

  return 0;
}

C++: /*
 * アルゴリズムとしてはチケットの枚数分のネットワークをレイヤ構造で持ち
 * 各々のレイヤから上位レイヤへはチケットを使った場合に遷移するようにする
 * 上位レイヤから下位レイヤには遷移することができないようにし，
 * 最下位レイヤの始点から終点と同じ点を表すすべてのレイヤの点までの最短経路を求める．
 *
 * (イメージ)
 *      T`T`T`  
 *      |/|/|   S=始点, o=点, T`=終点 |=辺 /=レイヤ下位から上位への有効辺
 *      o o o   
 *      |/|/|   S->T`までの距離で最短のものを求め出力する
 *      S o o   
 *Layer 0 1 2   
 *
 **/

#include <iostream>
#include <map>
#include <limits.h>

#define rep(i,s,t) for(int i=s;i<t;i++)

using namespace std;

//c層目のid値を返す関数
int id2cid(int c,int id){
	return c*1000+id;
}

//dijkstraアルゴリズム
//特に無加工，距離を持った隣接を表すgraphと各点までの距離を保持するdis,始点ssを入力
//計算結果はdisに保持し，返り値は無し
void dijkstra(map<int,map<int,int> > &graph,map<int,int>  &dis,int ss){
	//未確定点を保持する集合multimap，距離をkey,点idをvalueとする
	multimap<int, int> T;
	//注目する点pのid値
	int pid;
	//始点をまず入力する
	T.insert(make_pair(0,ss));
	//未確定点がなくなるまで
	while(!T.empty()){
		//未確定の中で一番距離が小さい要素(mapの先頭)を取得し注目点pを得る
		pid=(*(T.begin())).second;
		//点pを未確定点集合から削除する
		T.erase(T.begin());

		//pに隣接する点について
		for(map<int,int>::iterator it=graph[pid].begin();it!=graph[pid].end();it++){
			//隣接点のid値cidとその点までの距離distを取得
			int cid=(*it).first;
			int dist=(*it).second;
			//隣接点が未確定点集合に含まれない，もしくは暫定の距離より小さい場合
			//未確定点集合の隣接点の距離を始点から注目点までの距離＋注目点からの距離に更新する
			if((dis.find(cid)!=dis.end() &&  dis[cid]>dis[pid]+dist) ||
				dis.find(cid)==dis.end()){
					T.insert(make_pair(dis[pid]+dist,cid));			
					dis[cid]=dis[pid]+dist;
			}
		}
	}
}

int main(void){
	int c,n,m,s,d;
	//グラフ構造用意
	map<int,map<int,int> > graph;
	//各点の最短距離を保持するmap
	map<int,int>  dis;
	while(cin >> c >> n >> m >> s >> d){
		if(c==0) break;

		//グラフ構造を初期化
		graph.clear();
		//mapを用いて辺i,jのコストcで隣接関係を表現

		//m路線に対して
		rep(i,0,m){
			int a,b,f;
			cin >> a >> b >> f;

			//グラフをc+1個の層構造とする
			rep(j,0,c+1){
				//j層目のグラフでは通常料金の移動コストで辺を張る
				//id2cid(j,id)でj層目の点idを示すid値に変換する
				//点は最大でも500点しかないため，1000桁目以上がn層目とする.
				//ex(0層目の点125は id=125,8層目の点125は8125)となる．
				graph[id2cid(j,a)][id2cid(j,b)]=f;
				graph[id2cid(j,b)][id2cid(j,a)]=f;
				//j層目からj+1層目へは割引料金を用いた移動コストの辺を張る
				//j層目からj-1層目への辺がないため階層が上がるに連れて下がることはできない
				//j層目はすなわちj回チケットを利用した枚数に相当する．
				if(j<c){
					graph[id2cid(j,a)][id2cid(j+1,b)]=f/2;
					graph[id2cid(j,b)][id2cid(j+1,a)]=f/2;
				}
			}
		}
		rep(j,0,c+1){
			//各レイヤからダミー終点INT_MAXまで辺をはる
			graph[id2cid(j,d)][INT_MAX]=0;
		}
		//各点への最短距離を保持するmapの初期化
		dis.clear();
		//通常のダイクストラで始点sからの各点への最短距離を求め，計算結果を変数disに保持する
		dijkstra(graph,dis,id2cid(0,s));

		//結果出力
		cout << dis[INT_MAX] << endl;
	}

	return 0;
}

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

struct node{
  int cost;
  int c;
  int now;
  node(int C,int cc,int n):cost(C),c(cc),now(n){}
  bool operator >(const node &e) const{
    return cost > e.cost;
  }
};

int main()
{
  int c,n,m,s,d;

  for(;cin>>c>>n>>m>>s>>d,c;)
    {
      int edge[n][n];
      bool close[c+1][n];
      memset(edge,-1,sizeof(edge));
      memset(close,false,sizeof(close));      
      for(int i=0;i<m;i++)
	{
	  int a,b,f;
	  cin>>a>>b>>f;
	  a--;
	  b--;
	  edge[a][b]=f;
	  edge[b][a]=f;
	}
      s--;
      d--;
      priority_queue<node,vector<node>,greater<node> >qu;
      qu.push(node(0,c,s));
      while(!qu.empty())
	{
	  node tmp = qu.top();
	  //	  cout<<tmp.now<<" "<<tmp.cost<<" "<<tmp.c<<endl;
	  qu.pop();
	  close[tmp.c][tmp.now]=true;
	  if(tmp.now==d)
	    {
	      cout<<tmp.cost<<endl;
	      break;
	    }
	  for(int i=0;i<n;i++)
	    {
	      if(edge[tmp.now][i]!=-1)
		{
		  if(!close[tmp.c][i])
		    qu.push(node(edge[tmp.now][i]+tmp.cost,tmp.c,i));
		  if(tmp.c>0 && !close[tmp.c-1][i])
		    qu.push(node(edge[tmp.now][i]/2+tmp.cost,tmp.c-1,i));
		}
	    }
	}
    }

}