/*
HDU 4679 Terrorist’s destroy
给一棵树,任意删一条边,树分成了两个部分(a,b),求min( max(a.直径,b.直径) * v.w )
最大直径乘以边权 积的最小值
解法:
先找出整棵树的直径所在,即两个端点ds de
然后保存每个点到ds和de之间的距离 dds[] dde[]
然后从ds(de)开始搜
每个点保存子树中到de(ds)之间距离的最大值mde[](mds[]),这里要用到dds[]和dde[]
然后枚举删边,从ds(或de)开始搜
当删father,child之间的一条边的时候,分成了两个子树,我们的max(mde[father],mds[child])就是两个子树的最大直径
然后就没有然后了。。。。
几乎每一部操作都要搜两次
*/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <functional>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <vector>
#include <ctime>
#include <queue>
#include <cmath>
#include <set>
#define CLR(a,v) memset(a,v,sizeof(a))
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1<<29;
const int N = 1e5+10;
struct node{
int hid , w , pid; // houseid wight pathid
node(){}
node(int a,int b,int v):hid(a),w(b),pid(v){}
};
vector <node > m[N];
int ds,de; // 直径的端点
int dds[N],dde[N]; // 以ds、de为根深度
int mds[N],mde[N]; // 以ds(de)为根每个节点存其子树节点到de(ds)的最远距离
void dfs(int now,int fa,int& dtmp,int ddtmp[]){ // 求端点
if(m[now].size()==1 && m[now][0].hid==fa && ddtmp[now] > ddtmp[dtmp]){
// 如果是叶子
dtmp = now;return;
}
int child;
for(int i = 0 ; i < m[now].size() ; i++){
if( (child=m[now][i].hid) == fa)continue;
ddtmp[child] = ddtmp[now] + 1;
dfs(child,now,dtmp,ddtmp);
}
}
void dfs(int now,int fa,int mdtmp[],int ddtmp[]){ // 求最远距离
int child ;
mdtmp[now] = ddtmp[now];
for(int i = 0 ; i < m[now].size() ; i++){
if( (child=m[now][i].hid) == fa)continue;
dfs(child ,now , mdtmp,ddtmp);
mdtmp[now] = max(mdtmp[now],mdtmp[child]);
}
}
int ans , ansid;
void dfs(int now,int fa){ // 枚举删边,删完一条边后分成了两段
int child;
for(int i = 0; i < m[now].size() ; i++){
if( (child=m[now][i].hid) == fa )continue;
//判断是不是直径(判断两段的最长链相加等于直径长)dds[de]就是直径长
//int w = m[now][i].w * ( (dds[now] + dde[child] +1 == dds[de]) ? (max(mds[now] , mde[child])) : (dds[de]) );
int w = m[now][i].w * max(mds[now] , mde[child]);
if(w < ans){
ans = w;
ansid = m[now][i].pid;
}else if(w == ans && m[now][i].pid < ansid)
ansid = m[now][i].pid;
dfs(child,now);
}
}
int main(){
//freopen("in","r",stdin);
//freopen("out.txt","w",stdout);
// g++ 扩栈
//int size = 20 << 20; // 20MB
//char *p = (char*)malloc(size) + size;
//__asm__("movl %0, %%esp\n" :: "r"(p));
int T,n,trash=0,ca=1;cin >> T;
while(T--){
scanf("%d",&n);
for(int i = 1 ; i < n ; i++){
int a,b,v;
scanf("%d%d%d" , &a , &b , &v);
node c1(b,v,i),c2(a,v,i);
m[a].push_back(c1);
m[b].push_back(c2);
}
ds = de = 0;
CLR(dds,0);dds[1]=1;
dfs(1 , 0 , ds , dds); // only find ds
CLR(dde,0);CLR(dds,0);dde[ds]=1;
dfs(ds , 0 , de , dds); // find de and calc dds[]
dfs(de , 0 , trash , dde); // only calc dde[]
CLR(mds,0);mds[de]=0;
dfs(de,0,mds,dds);
CLR(mde,0);mde[ds]=0;
dfs(ds,0,mde,dde);
ans = ansid = INF;
dfs(ds,0);
printf("Case #%d: %d\n",ca++,ansid);
for(int i = 0 ; i <= n ; i++)
m[i].clear();
}
return 0;
}