HDU 3938:Portal(并查集+离线处理)
Posted Shadowdsp
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 3938:Portal(并查集+离线处理)相关的知识,希望对你有一定的参考价值。
http://acm.hdu.edu.cn/showproblem.php?pid=3938
Portal
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
3
6
2
16
13
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 #define N 10005 8 #define M 50005 9 /* 10 因为询问比较多,所以需要离线 11 在线的意思就是每一个询问单独处理复杂度O(多少多少), 12 离线是指将所有的可能的询问先一次都处理出来, 13 最后对于每个询问O(1)回答 14 15 对于每个询问有一个长度L,问有多少条路径的长度<=L 16 而且该路径的长度是T,T是从u到v上最长的边 17 只要求得有多少个点对使得点对之间的最大的边小于L即可。 18 19 先从小到大排序一遍询问的边的长度L,从小到大枚举u->v之间的边的长度 20 如果两个集合没有联通,那么联通之后路径的条数为sum[x]*sum[y] 21 因为长的L必定包含了短的L的答案,所以要累加起来 22 */ 23 int fa[N],sum[N]; 24 25 struct node1 26 { 27 int id,ans,l; 28 }query[N]; 29 30 struct node2 31 { 32 int u,v,len; 33 }edge[M]; 34 35 bool cmp1(node2 a,node2 b) 36 { 37 return a.len<b.len; 38 } 39 40 bool cmp2(node1 a,node1 b) 41 { 42 return a.id<b.id; 43 } 44 45 bool cmp3(node1 a,node1 b) 46 { 47 return a.l<b.l; 48 } 49 50 int Find(int x) 51 { 52 if(x==fa[x]) return x; 53 return fa[x]=Find(fa[x]); 54 } 55 56 int Merge(int x,int y) 57 { 58 int fx=Find(x),fy=Find(y); 59 if(fx==fy) return 0; 60 int tmp; 61 if(fx<fy){ 62 fa[fy]=fx; 63 tmp=sum[fx]*sum[fy]; 64 sum[fx]+=sum[fy]; 65 } 66 else{ 67 fa[fx]=fy; 68 tmp=sum[fx]*sum[fy]; 69 sum[fy]+=sum[fx]; 70 } 71 return tmp; 72 } 73 74 int main() 75 { 76 int n,m,q; 77 while(~scanf("%d%d%d",&n,&m,&q)){ 78 for(int i=1;i<=n;i++){ 79 fa[i]=i; 80 sum[i]=1; 81 } 82 for(int i=0;i<m;i++){ 83 scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].len); 84 } 85 for(int i=0;i<q;i++){ 86 scanf("%d",&query[i].l); 87 query[i].id=i; 88 query[i].ans=0; 89 } 90 sort(edge,edge+m,cmp1); 91 sort(query,query+q,cmp3); 92 int cnt=0; 93 for(int i=0;i<q;i++){ 94 while(edge[cnt].len<=query[i].l&&cnt<m){ 95 int x=edge[cnt].u; 96 int y=edge[cnt].v; 97 int fx=Find(x); 98 int fy=Find(y); 99 if(fx==fy) cnt++; 100 else{ 101 query[i].ans+=Merge(x,y); 102 cnt++; 103 } 104 } 105 if(i>0) query[i].ans+=query[i-1].ans; 106 } 107 sort(query,query+q,cmp2); 108 for(int i=0;i<q;i++){ 109 printf("%d\n",query[i].ans); 110 } 111 } 112 return 0; 113 }
以上是关于HDU 3938:Portal(并查集+离线处理)的主要内容,如果未能解决你的问题,请参考以下文章