hdu3938 Portal

来源:互联网 发布:软件开发网校 编辑:程序博客网 时间:2024/06/05 05:34
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 107 2 16 8 34 5 85 8 22 8 96 4 52 1 58 10 57 3 77 8 810615918276
 

Sample Output
361311336136216
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;}


0 0