先按边权值排个序,每次加入一条边,用并查集,关键看懂题。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAXN = 10010;
int N,M,Q;
struct Edge{
int a,b;
int cost;
void input(){
scanf("%d%d%d",&a,&b,&cost);
a--;b--;
}
}edges[MAXN*5];
inline int cmp(Edge a,Edge b){
return a.cost < b.cost;
}
struct Qs{
int index,t;
}q[MAXN];
int ans[MAXN];
inline int cmp1(Qs a,Qs b){
return a.t < b.t;
}
int f[MAXN],r[MAXN];
inline int find(int x){
if(x != f[x]){
f[x] = find(f[x]);
}
return f[x];
}
int main(){
while (scanf("%d%d%d",&N,&M,&Q) != EOF){
for(int i = 0; i < M; ++i)edges[i].input();
sort(edges,edges+M,cmp);
for(int i = 0; i < Q; ++i){
scanf("%d",&q[i].t);
q[i].index = i;
}
sort(q,q+Q,cmp1);
int st = 0,sum;
for(int i = 0; i < N; ++i){
r[i] = 1;f[i] = i;
}
sum = 0;
for(int i = 0; i < Q; ++i){
while (st < M && q[i].t >= edges[st].cost){
if(find(edges[st].a) != find(edges[st].b)){
int a = r[f[edges[st].a]],b = r[f[edges[st].b]];
sum += (a+b)*(a+b-1)/2 - a*(a-1)/2 - b*(b-1)/2;
r[f[edges[st].a]] = a+b;
f[f[edges[st].b]] = f[edges[st].a];
}
st ++;
}
ans[q[i].index] = sum;
}
for(int i = 0; i < Q; ++i){
printf("%d\n",ans[i]);
}
}
return 0;
}