Input There are multiple test cases. The first line of input contains three integer N, M and Q (1 < N ≤ 10,000, 0 < M ≤ 50,000, 0 < Q ≤ 10,000). N is the number of points, M is the number of edges and Q is the number of queries. Each of the next M lines contains three integers a, b, and c (1 ≤ a, b ≤ N, 0 ≤ c ≤ 10^8) describing an edge connecting the point a and b with cost c. Each of the following Q lines contain a single integer L (0 ≤ L ≤ 10^8).
Output Output the answer to each query on a separate line.
Sample Input
10 10 10
7 2 1
6 8 3
4 5 8
5 8 2
2 8 9
6 4 5
2 1 5
8 10 5
7 3 7
7 8 8
10
6
1
5
9
1
8
2
7
6
Sample Output
36
13
1
13
36
1
36
2
16
13
/*
离线并查集,边按小到大排序,询问也按小到大排序;
对于询问x,答案就是询问x-1的值加上询问x-1的L1和询问x的L2之间的边合并带来的值
对于一条属于L1和L2之间的边,如果端点u,v在一个集合中,忽略,否则新开的路是u
所在集合的大小乘上v所在集合的大小
*/
#include<stdio.h>
#include<algorithm>
using namespace std;
int n,m,q,ans[10010];
int hav[50010],father[50010];
struct node
{
int u,v,w;
}edge[50010];
int cmp1(node a,node b)
{
return a.w<b.w;
}
struct que
{
int num,v;
}qu[10010];
int cmp2(que a,que b)
{
return a.v<b.v;
}
void init()
{
int i;
for(i=0;i<m;i++)
scanf("%d %d %d",&edge[i].u,&edge[i].v,&edge[i].w);
for(i=1;i<=n;i++)
{
father[i]=i;
hav[i]=1;
}
for(i=1;i<=q;i++)
{
scanf("%d",&qu[i].v);
qu[i].num=i;
}
sort(edge,edge+m,cmp1);
sort(qu+1,qu+q+1,cmp2);
}
int find(int i)
{
int x,y,j;
x=i;
while(x!=father[x]) x=father[x];
y=i;
while(y!=father[y])
{
j=father[y];
father[y]=x;
y=j;
}
return x;
}
void unin(int u,int v)
{
father[u]=v;
hav[v]+=hav[u];
}
void solve()
{
int i,j,u,v;
j=0;
ans[0]=0;
for(i=1;i<=q;i++)
{
ans[qu[i].num]=ans[qu[i-1].num];
while(edge[j].w<=qu[i].v&&j<m)
{
u=find(edge[j].u);
v=find(edge[j].v);
if(u!=v)
{
ans[qu[i].num]+=hav[u]*hav[v];
unin(u,v);
}
j++;
}
}
for(i=1;i<=q;i++)
{
printf("%d\n",ans[i]);
}
}
int main()
{
while(scanf("%d %d %d",&n,&m,&q)!=EOF)
{
init();
solve();
}
return 0;
}