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
 
题目意思:
            给定一张无向图,要你求出满足小于或等于给定边长的最多边长的种类数目。当然关键是有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 }
View Code

 

 

你可能感兴趣的:(Portal)