hdu 3948 Portal (kusral+离线)

Portal

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 931    Accepted Submission(s): 466

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

Source

2011 Multi-University Training Contest 10 - Host by HRBEU

题目意思:

给定一张无向图,要你求出满足小于或等于给定边长的最多边长的种类数目。当然关键是有n次询问。

思路:

对于一颗有n条路径的无向图,可以知道,当与另一个m条路径的无向图合并为一个全新的无向图时: 此时的路径为 n*m;

当然这题的重点不在这里,此题关键是有q次询问,对于每一次询问,若我们都去重新求解一次,将会很花时间,无疑TLE倒哭。%>_<%

于是采用离线处理(这里是开了解题报告才想起来,这么巧妙的地方,果然是too yong 哇! ):

离线的思路为:   先将询问的权值从小到大排序,由于大的权值包含了小的权值,于是整个过程,居然只需要一次就搞定。  俺是乡下人,第一次见识到这点,吓尿了!╮(╯▽╰)╭

代码:

 1 #define LOCAL
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 #include<cstdlib>
 7 using namespace std;
 8 const int maxn=10005;
 9 /*for point*/
10 struct node{
11     int a,b,c;
12     bool operator <(const node &bn)const {
13        return c<bn.c;
14     }
15 }sac[maxn*5];
16 /*for query*/
17 struct query{
18    int id,val;
19    bool operator <(const query &bn)const {
20        return val<bn.val;
21    }
22 }qq[maxn];
23
24 int father[maxn],rank[maxn];
25 int key[maxn];
26
27 void init(int n){
28     for(int i=0;i<=n;i++){
29         father[i]=i;
30         rank[i]=1;
31     }
32 }
33
34 int fin(int x){
35   while(x!=father[x])
36          x=father[x];
37   return x;
38 }
39
40 int unin(int x,int y)
41 {
42    x=fin(x);
43    y=fin(y);
44    int ans=0;
45     if(x!=y){
46        ans=rank[x]*rank[y];
47      if(rank[x]<rank[y]){
48          rank[y]+=rank[x];
49          father[x]=y;
50      }
51     else{
52           rank[x]+=rank[y];
53          father[y]=x;
54     }
55     }
56    return ans;
57 }
58
59 int main()
60 {
61     #ifdef LOCAL
62        freopen("test.in","r",stdin);
63        freopen("test1.out","w",stdout);
64     #endif
65   int n,m,q;
66   while(scanf("%d%d%d",&n,&m,&q)!=EOF)
67   {
68         init(n);
69        for(int i=0;i<m;i++){
70         scanf("%d%d%d",&sac[i].a,&sac[i].b,&sac[i].c);
71      }
72
73      for(int i=0;i<q;i++){
74        scanf("%d",&qq[i].val);
75         qq[i].id=i;
76      }
77      sort(sac,sac+m);
78      sort(qq,qq+q);
79      int i,j,res=0;
80      for(j=0,i=0;i<q;i++){
81          while(j<m&&sac[j].c<=qq[i].val){
82             res+=unin(sac[j].a,sac[j].b);
83             ++j;
84         }
85         key[qq[i].id]=res;
86      }
87      for(i=0;i<q;i++){
88             printf("%d\n",key[i]);
89      }
90   }
91   //  system("comp");
92
93    return 0;
94 }

时间: 2024-10-06 02:38:02

hdu 3948 Portal (kusral+离线)的相关文章

hdu 3948 后缀数组

The Number of Palindromes Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 2465    Accepted Submission(s): 841 Problem Description Now, you are given a string S. We want to know how many distin

HDU 3333 Turing Tree (离线询问+线段树)

题目地址:HDU 3333 将询问离线保存下来,然后将数组的点离散化,记录每个值上一次出现的位置.然后枚举数组的数,若当前枚举的数前面出现过,那么就删掉前面出现过的那个位置上的数,更新当前这个位置上的数,然后那些所有询问的右端点为当前位置的就可以通过查询来得到结果了. 更新与查询用线段树来优化. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #

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两点间

HDU 5179 beautiful number 离线处理

传送门:http://acm.hdu.edu.cn/showproblem.php?pid=5179 beautiful number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 176    Accepted Submission(s): 104 Problem Description Let A=∑ni=1ai?10n?i(1≤

hdu 4288 线段树+离线+离散化

http://acm.hdu.edu.cn/showproblem.php?pid=4288 开始的时候,果断TLE,做的方法是,线段树上仅仅维护%5==3的坐标,比如1 2 3 4 5 6 7  如果删除第三个数,就将3,6的位置全+1,就是向右偏移以为,但是求和还是很慢,所以即使10秒,还是TLE... 正确做法: 1.节点内维护sum[0...4]分别代表区间内%5==i的和 2.结点维护点的个数,cnt 3.离散化处理,然后每次插入时,经过的结点cnt+1或-1,叶子节点Sum[0]就是

hdu 3948 The Number of Palindromes

The Number of Palindromes Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)http://acm.hdu.edu.cn/showproblem.php?pid=3948 Problem Description Now, you are given a string S. We want to know how many distinct substri

HDU - 3948 后缀数组+Manacher

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3948 题意:给定一个字符串,求字符串本质不同的回文子串个数. 思路:主要参考该篇解题报告 先按照manacher的构造方法改造一遍串,然后跑一遍manacher.求出以i为中心的最长回文串长度p[i]. 然后跑一遍后缀数组,若已经求得后缀sa[i-1]对答案的贡献,然后现在计算后缀sa[i],本来是要加上以sa[i]为中心的回文串的个数p[sa[i]]. 我们可以维护一个tmp,也就是上图中蓝色的框

hdu 2586(Tarjan 离线算法)

How far away ?                                                                             Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)                                                                            

HDU 4417 Super Mario(离线线段树or树状数组)

Problem Description Mario is world-famous plumber. His "burly" figure and amazing jumping ability reminded in our memory. Now the poor princess is in trouble again and Mario needs to save his lover. We regard the road to the boss's castle as a l