走廊潑水節
阿新 • • 發佈:2020-08-15
題目描述
話說,中中帶領的 們打算舉行一次冬季潑水節,當然這是要祕密進行的,絕對不可以讓中中知道。不過中中可是老江湖了,當然很快就發現了我們的小陰謀,於是他準備好水槍迫不及待的想要加入我們了。
我們一共有 個 打算參加這個潑水節,同時很湊巧的是正好有 個水龍頭(至於為什麼,我不解釋)。 個水龍頭之間正好有 條小道,並且每個水龍頭都可以經過小道到達其他水龍頭(這是一棵樹,你應該懂的..)。但是 門為了迎接中中的挑戰,決定修建一些個道路(至於怎麼修,祕密~),使得每個水龍頭到每個水龍頭之間都有一條直接的道路連線(也就是構成一個完全圖唄~)。但是OIER門很懶得,並且記性也不好,他們只會去走那 條小道,並且希望所有水龍頭之間修建的道路,都要大於兩個水龍頭之前連線的所有小道(小道當然要是最短的了)。所以神 們,幫那些 們計算一下吧,修建的那些道路總長度最短是多少,畢竟修建道路是要破費的~~
輸入格式
第一行t,表示有t組測試資料
對於每組資料,第一行N,表示水龍頭的個數(當然也是OIER的個數);
2到N行,每行三個整數X,Y,Z;表示水龍頭X和水龍頭Y有一條長度為Z的小道
輸出格式
對於每組資料,輸出一個整數,表示修建的所有道路總長度的最短值。
樣例
樣例輸入
2
3
1 2 2
1 3 3
4
1 2 3
2 3 4
3 4 5
樣例輸出
4
17
樣例解釋
第一組資料,在2和3之間修建一條長度為4的道路,是這棵樹變成一個完全圖,且原來的樹依然是這個圖的唯一最小生成樹.
資料範圍與提示
每個測試點最多組測試資料
;
程式碼
#include <bits/stdc++.h>
using namespace std;
const int maxn=6000+100;
struct node{
int from,to,next,w;
bool operator < (const node&a)const{return w < a.w;}
}e[maxn<<1];
int head[maxn];int cnt;
void add(int x,int y,int z){e[++cnt]=(node){x,y,head[x],z};head[x]=cnt;}
inline int read(){
int k=0,f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar()) k=k*10+ch-'0';
return k*f;
}
int f[maxn],w[maxn];
int find(int x){return f[x]==x?x:(f[x]=find(f[x]));}
int main(){
int T=read();
while(T--){
int n=read();
for(int i=1;i<=n;i++) f[i]=i,w[i]=1;
cnt=0;
for(int i=1;i<n;i++){int x=read(),y=read(),z=read();add(x,y,z+1);}
sort(e+1,e+n);
int tmp=0;
for(int i=1;i<n;i++){
int u=find(e[i].from),v=find(e[i].to);
tmp+=(w[u]*w[v]-1)*e[i].w;
f[u]=v; w[v]+=w[u];
}
printf("%d\n",tmp);
}
}