Problem:
サージェント・ライアン

「ライアン軍曹を救え」という指令のもと、アイヅ軍の救出部隊はドイツリーの水上都市で敵軍と激しい戦闘を繰り広げていました。彼らは無事に軍曹と合流しましたが、敵の戦車が多く、救出ヘリを呼べずにいました。そこで、彼らは敵の戦車を混乱させるため、都市にある橋を全て爆破するという作戦を実行することにしました。

作戦はすぐに司令部に伝えられ、救出ヘリの準備が進められました。救出ヘリを飛ばすためには、いつ橋が全て爆破されるかを予測しなければなりません。軍のプログラマであるあなたの任務は、救出部隊が全ての橋の爆破に必要な時間を計算することです。

水上都市は N 個の島で構成されており、島と島との間には橋がかかっています。すべての島はツリー状に繋がっています(下図参照) 。ある島からある島への経路は、一通りだけ存在します。各橋を渡るには、橋ごとに決められた時間がかかり、どちらの方向にもその時間で橋を渡ることが可能です。

救出部隊はボートなど水上を移動する手段を持っていないので島と島の間を移動するには橋を通る他ありません。救出部隊は、その時いる島に隣接している橋のうち、必要なものを一瞬で爆破することができます。救出部隊が全ての橋を爆破するのに必要な最小の時間はいくらでしょうか。ただし、島の中での移動時間は考えません。

島の数、それぞれの橋情報を入力とし、橋を全て爆破するのに必要な最小の時間を出力するプログラムを作成してください。島はそれぞれ 1 から N の番号で表されます。橋は N-1 本あります。橋情報は、その橋が隣接している二つの島の番号(a, b)と、その橋を渡るのに必要な時間 t で構成されます。救出部隊は島番号 1 の島からスタートするものとします。

Input

複数のデータセットの並びが入力として与えられる。入力の終わりはゼロひとつの行で示される。各データセットは以下の形式で与えられる。

N
a1 b1 t1
a2 b2 t2
:
aN-1 bN-1 tN-1

入力はすべて整数で与えられる。1 行目に島の数 N (2 ≤ N ≤ 20) が与えられる。

続く N-1 行に i 番目の橋の情報が与えられる。 ai, bi, ti (1 ≤ ti ≤ 500) は、i 番目の橋を通って島 ai と島 bi の間を時間 ti で移動できることを表す。

データセットの数は 100 を超えない。

Output

データセットごとに、橋を全て爆破するのに必要な最小の時間を1行に出力する。

Sample Input

7
1 2 5
2 3 2
3 4 3
2 5 3
5 6 3
5 7 8
0

Output for the Sample Input

12

Solution in PHP (judge verdict: Wrong Answer)

<?php
//ある島からある島への経路は１通りしかない" という記述から, 閉路がない木構造であることがわかります. 
//つまり, １の島を根とする木構造となります.
//木構造の葉にあたる島にかかる橋は, その手前の島から爆破できるため, 絶対に渡らないことがわかります.
//また, 必ず最後は, 葉の親となる島で終わることがわかります.
//葉の親となる島はいくつか存在しますが, 島１からの到達時間が一番長いところが最後に訪問する島となります.
//結果, プログラムは, 次のように単純なものになります.
//葉にあたる島以外の島へかかる橋の時間のコストを全て足し合わせて２倍 = sum
//根（１の島）から葉の親までの到達時間の中で, 一番最大のものを sum から引くと, これが答え

$file_handle = fopen('php://stdin', "r");	//fopen()は同位フォルダにファイルがあればその名前のみでOK
//$file_handle = fopen('aoj0235_in.txt', "r");

//dfs（再帰ver）
function dfs($cur) {
	//グローバル変数定義
	global $n;
	global $island;
	global $sum_dist;
	global $goal_dist;
	global $dist;
	global $flag;
	
	//終了条件
	if ($flag===1){ return; }
	
    $island[$cur['node']] = true;		//現在の島を探索済みに追加
    
    //var_dump ($n);
    
    if (isset($dist[$cur['parent']][$cur['node']])){
       $sum_dist += $dist[$cur['parent']][$cur['node']];
    }
    
    $childnode = childnode($cur['node']);
    foreach ($childnode as $island_num => $distance) {
	   $grandchildnode = childnode($island_num);
       if (!empty($grandchildnode)) {
       		$new['node'] = $island_num;
    		$new['parent'] = $cur['node'];
    		dfs($new);
       } else {
        	$island[$island_num] = true;		//孫ノードが無い子ノードを爆破
       }
    }
    
    //終了条件
    if ($flag===1) {return;}
    $cnt = 0;
    for ($i=1; $i<=$n; $i++){
       if ( $island[$i] === false ){
           break;
       }
       $cnt++;
    }
    if ($cnt === $n && $flag === 0){
       $flag = 1;
       $goal_dist = $sum_dist;
       return;
    }

    if ($flag === 0 && !empty($dist[$cur['parent']][$cur['node']])){
		$sum_dist += $dist[$cur['parent']][$cur['node']];
	}
}

//子ノード抽出
function childnode($island){
	global $dist;
   //数字の大きい島のみ子ノードとして取り出す
   $childnode = array();
   if (!empty($dist[$island])){
	   foreach ($dist[$island] as $key => $val){
	       if ($island < $key){
	       		$childnode[$key] = $val;
	       }
	   }
   }
   asort($childnode);
   return $childnode;
}


while (1){
	//変数の初期化
	$island = array();
	$sum_dist = 0;
	$goal_dist = 0;
	$flag = 0;
	$dist = array();

	//ファイル読み込み
	$stdin = fscanf($file_handle, '%d');	//fscanf()で読み込んだものは配列として格納される
	$n = $stdin[0];
	//終了条件
	if ($n === 0){
		break;
	}
	
	for ($i=0; $i < $n-1; $i++){
		$info = fscanf($file_handle, '%d %d %d');
		$parent = $info[0]; $child = $info[1]; $distance = $info[2];
		if ($parent < $child){
			$dist[$parent][$child] = $distance;
		} else {
			$dist[$child][$parent] = $distance;
		}
	}
	for ($i=1; $i<=$n; $i++){
		//全ての島についてfalseを入れる。
		$island[$i] = false;
	}

	//探索
	$stack['node'] = 1;		//スタートを$stackに入れて開始
	$stack['parent'] = null;
	dfs($stack);

	//出力
	if ($flag === 1){
		echo $goal_dist;
	} else {
		echo 'ERROR';
	}
	echo PHP_EOL;
}

fclose($file_handle);