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 }
时间: 2024-10-27 19:19:23

HDU 3938:Portal(并查集+离线处理)的相关文章

Hdu 2473(并查集删除操作) Junk-Mail Filter

有木有很吊 加强 加强版   啊  ,看了都不敢做了   ,后来先做了食物链这个我还是看过的,但还是A不掉,没明白神魔意思 ,总而言之,大牛的博客是个好东西,我就那么看了一下,还是不懂怎莫办啊,哎,就那样就A掉了....... 今天我们来谈一下这个并查集的删除操作,根据我对大牛的理解啊,这个并查集的删除操作并不是把原来的节点删除掉,而是用一个替身替掉,现在的这个点只是用作桥梁的作用,即是无用的,del  ,,,del  ,,,,删除,那些被删掉的就从n开始给他们一个地址,然后即如下代码所示 #i

HDU 4496 D-City(并查集,逆思维)

题目 熟能生巧...常做这类题,就不会忘记他的思路了... //可以反过来用并查集,还是逐个加边,但是反过来输出...我是白痴.....又没想到 //G++能过,C++却wa,这个也好奇怪呀... #include<stdio.h> #include<string.h> int fx,fy,r,bin[10010]; int x[100010],y[100010],n,m,i,count,ans[100010],j; int find(int x) { //改成这样就不会超时了么好

HDU 1272 简单并查集

小希的迷宫 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 24915    Accepted Submission(s): 7641 Problem Description 上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双

hdu 3038 (并查集)

题目大意: 给出m个询问,问[l,r]之间的和   ,求出有多少次询问不和之前的矛盾的. 思路分析: 用并查集记录当前节点到根节点的和. #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #define maxn 222222 using namespace std; int set[maxn]; int sum[maxn]; int find(int

ACM学习历程—SNNUOJ 1110 传输网络((并查集 &amp;&amp; 离线) || (线段树 &amp;&amp; 时间戳))(2015陕西省大学生程序设计竞赛D题)

Description Byteland国家的网络单向传输系统可以被看成是以首都 Bytetown为中心的有向树,一开始只有Bytetown建有基站,所有其他城市的信号都是从Bytetown传输过来的.现在他们开始在其他城市陆 续建立了新的基站,命令“C x“代表在城市x建立了一个新的基站,不会在同一个城市建立多个基站:城市编号为1到n,其中城市1就是首都Bytetown.在建立基站的过程中他们还 会询问某个城市的网络信号是从哪个城市传输过来的,命令”Q x“代表查询城市x的来源城市. Inpu

hdu 3938 Portal(并查集+离线+kruskal)

搜了题解才把题搞明白.明白之后发现其实题意很清晰,解题思路也很清晰,只是题目表述的很不清晰…… 大意如下—— 给你一个无向图,图中任意两点的距离是两点间所有路径上的某一条边,这条边需要满足两个条件:1. 这条边这两点间某条路径上的最长边:2. 这条边是这两点间所有路径上的最长边中的最短边. 简单来说,假如a到d有两条路径,一条经过b,一条经过d,其中ab = 1, bd = 3, ac = 2, cd = 2,那么abd上的最长边为3,acd上的最长边为2,则ad的距离为2. 如果a, d两点间

hdu5441(并查集+离线处理)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5441 题意: 根据输入的三个整数n.m.q,表示有n座城市,m条路,q次询问.下面给出m行,每行三个数start.end.w,分别是这条道路的起点城市.终点城市."权值".然后给出q次询问的数值,每次询问的结果是符合条件的路有多少条.条件就是:如果这条路的权值比给的限制值要小,那么这条路就是可行的.注意就是:对于一条路的添加来说,只要a到b之间有路,那么符合条件的路就会有两条,一条是a到b

BZOJ 1015 星球大战 并查集+离线

这道题说来真是艰辛,从一开始的RE,到RE,到刚刚的WA,再到AC. 这只能说明我进步的历程,还有我需要不断的加强努力.这道题思路不难,从很久前在黑书中并查集一节就能找到解题的踪影,因为并查集只能并,分不了,所以我们就得离线,倒过来写.只不过这道题真的得审好题目,它问的是剩下的星球中有多少个连通分量,不要搞错了.大概就是这个样子了,加油. 1 #include<cstdio> 2 #include<iostream> 3 #define rep(i,j,k) for(int i=

hdu 4496 D-City 并查集

D-City Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 2317    Accepted Submission(s): 814 Problem Description Luxer is a really bad guy. He destroys everything he met. One day Luxer went to D-