Problem Description
ZLGG found a magic theory that the bigger banana the bigger banana peel .This important theory can help him make a portal in our universal. Unfortunately, making a pair of portals will cost min{T} energies. T in a path between point V and point U is the length
of the longest edge in the path. There may be lots of paths between two points. Now ZLGG owned L energies and he want to know how many kind of path he could make.
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 题目要求a、b两点之间所有的路径中的最大边的最小值。 这题可以用并查集做,因为询问次数很多,所以要离线操作。设数组num[i],只记录i所在集合的总顶点数(一开始以为是记录边的,其实是记录顶点的),先对所有的边排序,从小到大,(其实可以看做是依次枚举最大边的最小值,因为如果这条线段的两端点不在一个集合,即两个集合的边不相连,那么这条线段就起到了桥梁的作用,也就是说任意两个集合的点相连都要通过这条边,因为之前两个集合的最大边的最小值都符合条件,那么如果这条线段也符合条件,就可以把两个集合的点都连起来),因为能量大的值一定包括能量小的路径,所以每次初始化的时候p[i].sum=p[i-1].sum;#include<iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<map> #include<string> using namespace std; int pre[10006],num[10006]; struct edge { int from,to,len; }e[50006]; struct node { int id,num,sum; }q[10006]; bool cmp1(edge a,edge b) { int temp; if(a.len>b.len){ temp=a.from;a.from=b.from;b.from=temp; temp=a.to;a.to=b.to;b.to=temp; return a.len<b.len; } return a.len<b.len; } bool cmp2(node a,node b) { int temp; if(a.num>b.num){ temp=a.id;a.id=b.id;b.id=temp; return a.num<b.num; } return a.num<b.num; } bool cmp3(node a,node b) { int temp; if(a.id>b.id){ temp=a.sum;a.sum=b.sum;b.sum=temp; return a.id<b.id; } return a.id<b.id; } int find(int x) { int r=x,i,j=x; while(r!=pre[r])r=pre[r]; while(j!=pre[j]){ i=pre[j]; pre[j]=r; j=i; } return r; } int main() { int n,m,i,j,a,b,c,p,t1,t2,ans; while(scanf("%d%d%d",&n,&m,&p)!=EOF) { for(i=0;i<=n;i++){ pre[i]=i;num[i]=1; } for(i=1;i<=m;i++){ scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].len); } sort(e+1,e+1+m,cmp1); for(i=1;i<=p;i++){ scanf("%d",&q[i].num); q[i].id=i; } sort(q+1,q+p+1,cmp2); ans=1; q[0].sum=0; for(i=1;i<=p;i++){ q[i].sum=q[i-1].sum; while(ans<=m && e[ans].len<=q[i].num){ t1=find(e[ans].from);t2=find(e[ans].to); if(t1==t2){ ans++;continue; } pre[t1]=t2; q[i].sum+=num[t1]*num[t2]; num[t2]+=num[t1]; ans++; } } sort(q+1,q+1+p,cmp3); for(i=1;i<=p;i++){ printf("%d\n",q[i].sum); } } return 0; }