L i n k Link Link
D e s c r i p t i o n Description Description
S a m p l e Sample Sample I n p u t Input Input
1
5 5 3
2 3 6334
1 5 15724
3 5 5705
4 3 12382
1 3 21726
6000
10000
13000
S a m p l e Sample Sample O u t p u t Output Output
2
6
12
H i n t Hint Hint
S o l u t i o n Solution Solution
将边权和询问排序,每次按照询问选取可用的点,将这些点分为多块(用并查集),然后记录贡献就好了
C o d e Code Code
#include<algorithm>
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
ll ans, t[250005];
int test, n, m, q;
int f[250005], size[250005];
struct node
{
int x, y, z;
}a[400005];
struct awsl
{
int x, y;
}b[400005];
bool cmpx(awsl x, awsl y)
{return x.x < y.x;}
bool cmp(node x, node y)
{return x.z < y.z;}
int find(int x)
{
if (f[x] == x) return x;
else return f[x] = find(f[x]);
}
int main()
{
// freopen("1.out", "w", stdout);
scanf("%d", &test);
for(int e = 1; e <= test; ++e)
{
scanf("%d%d%d", &n, &m, &q);
for (int i = 1; i <= m; ++i)
scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
for (int i = 1; i <= n; ++i)
f[i] = i, size[i] = 1;
for (int i = 1; i <= q; ++i)
scanf("%d", &b[i].x), b[i].y = i;
sort(a + 1, a + m + 1, cmp);
sort(b + 1, b + q + 1, cmpx);
ans = 0; int j = 1;
for (int i = 1; i <= q; ++i)
{
while(a[j].z <= b[i].x && j <= m)
{
int x = find(a[j].x), y = find(a[j].y);
if (x > y) swap(x, y);
if (x != y)
{
ans += (ll)2 * size[x] * size[y];
f[x] = y; size[y] += size[x];
}
++j;
}
t[b[i].y] = ans;
}
for (int i = 1; i <= q; ++i)
printf("%lld\n", t[i]);
}
return 0;
}