0%

开车

有n个城市,被m条无向边连接,每条边有一个开车经过所需要的时间。
Jack开车的时间不能连续超过x分钟,也就是需要开车时间超过x的边,他不会走。
求有多少对城市(a,b),满足他可以开车从a城市到达b城市。

输入描述:

第一行3个整数n,m和q。
接下来m行,每行3个整数a,b,c.表示一条连接a和b的边,长度为c。
接下来q行,每行一个整数x,表示一次询问。

输出描述:

对于每个询问,输出相应的结果。

示例1
输入

5 5 3
2 3 6334
1 5 15724
3 5 5705
4 3 12382
1 3 21726
6000
10000
13000

输出

2
6
12

说明

n,q<=20000, c,m<=10^5

kaiche.cppview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <bits/stdc++.h>
#define MN 20005
#define ll long long
using namespace std;
struct Edge {
int a,b,x;
bool operator < (const Edge &m) const {
return x<m.x;
}
};
Edge e[100005];
int ufs[MN],siz[MN];
int find(int x) {
return x==ufs[x]?x:ufs[x]=find(ufs[x]);
}
ll Union(int a,int b) {
a=find(a);
b=find(b);
if(a==b)return 0;
ll ans=(ll)siz[a]*siz[b];
siz[a]+=siz[b];
ufs[b]=a;
return ans;
}
struct Ques {
int id,x;
bool operator < (const Ques &m) const {
return x<m.x;
}
};
Ques q[5005];
ll out[5005];
int main() {
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=1; i<=n; i++) {
ufs[i]=i;
siz[i]=1;
}
for(int i=1; i<=m; i++)
scanf("%d%d%d",&e[i].a,&e[i].b,&e[i].x);
for(int i=1; i<=k; i++)
scanf("%d",&q[i].x),q[i].id=i;
sort(e+1,e+1+m);
sort(q+1,q+1+k);
ll ans=0;
for(int i=1,j=1; i<=k; i++) {
while(j<=m&&e[j].x<=q[i].x) {
ans+=Union(e[j].a,e[j].b);
j++;
}
out[q[i].id]=ans;
}
for(int i=1; i<=k; i++)
printf("%lld\n",out[i]*2);
return 0;
}