zoukankan      html  css  js  c++  java
  • hdu 4750 Count The Pairs(并查集+二分)

    Problem Description

      
    With the 60th anniversary celebration of Nanjing University of Science and Technology coming soon, the university sets n tourist spots to welcome guests. Of course, Redwood forests in our university and its Orychophragmus violaceus must be recommended as top ten tourist spots, probably the best of all. Some undirected roads are made to connect pairs of tourist spots. For example, from Redwood forests (suppose it’s a) to fountain plaza (suppose it’s b), there may exist an undirected road with its length c. By the way, there is m roads totally here. Accidently, these roads’ length is an integer, and all of them are different. Some of these spots can reach directly or indirectly to some other spots. For guests, they are travelling from tourist spot s to tourist spot t, they can achieve some value f. According to the statistics calculated and recorded by us in last years, We found a strange way to calculate the value f:
      From s to t, there may exist lots of different paths, guests will try every one of them. One particular path is consisted of some undirected roads. When they are travelling in this path, they will try to remember the value of longest road in this path. In the end, guests will remember too many longest roads’ value, so he cannot catch them all. But, one thing which guests will keep it in mind is that the minimal number of all these longest values. And value f is exactly the same with the minimal number.
      Tom200 will recommend pairs (s, t) (start spot, end spot points pair) to guests. P guests will come to visit our university, and every one of them has a requirement for value f, satisfying f>=t. Tom200 needs your help. For each requirement, how many pairs (s, t) you can offer?
     
    Input
      
    Multiple cases, end with EOF.
      First line:n m
      n tourist spots ( 1<n<=10000), spots’ index starts from 0.
      m undirected roads ( 1<m<=500000).
    
      Next m lines, 3 integers, a b c
      From tourist spot a to tourist spot b, its length is c. 0<a, b<n, c(0<c<1000000000), all c are different.
    
      Next one line, 1 integer, p (0<p<=100000)
      It means p guests coming.
    
      Next p line, each line one integer, t(0<=t)
      The value t you need to consider to satisfy f>=t.
     
    Output
     
     For each guest's requirement value t, output the number of pairs satisfying f>=t.
      Notice, (1,2), (2,1) are different pairs.
     
    Sample Input
    2 1
    0 1 2
    3
    1
    2
    3
    3 3
    0 1 2
    0 2 4
    1 2 5
    5
    0 
    2
    3
    4
    5
     
    Sample Output
    2
    2
    0
    6
    6
    4
    4
    0
     
    Source
     
     

    题目大意:

    给一无向图,n个点,m条边,每条边有个长度,且不一样。定义f(i,j)表示从节点i到节点j的所有路径中的最大边权值的最小值。有q个询问,每个询问有个t,求f(i,j)>=t的种数。

    解题思路:

    并查集+简单dp+二分。

    思路,先按边从小到大排序考虑,对于每条边E该边两个节点为a、b,如果a、b不在同一个联通块,则a联通块中点集A和b联通块中点集B的f值一定为E(因为E升序)。恰好能使其通路。

    map[i]表示以权值为i的边作为f值的点对个数。

    sum[i]表示以大于等于第i大边权值的权值作为f值得点对总的个数。

    对于每一个t,在排序了的sig[i](能取的边权值)中二分找到大于等于它的最小的小标j。输出sum[j]即可。

    注意:

    求点对个数时要乘以2.

     1 #pragma comment(linker, "/STACK:1024000000,1024000000")
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<math.h>
     7 #include<algorithm>
     8 #include<queue>
     9 #include<set>
    10 #include<bitset>
    11 #include<map>
    12 #include<vector>
    13 #include<stdlib.h>
    14 #include <stack>
    15 using namespace std;
    16 #define PI acos(-1.0)
    17 #define max(a,b) (a) > (b) ? (a) : (b)  
    18 #define min(a,b) (a) < (b) ? (a) : (b)
    19 #define ll long long
    20 #define eps 1e-10
    21 #define MOD 1000000007
    22 #define N 10006
    23 #define M 600000
    24 #define inf 1e12
    25 int n,m;
    26 struct Node{
    27     int x,y;
    28     int cost;
    29 }node[M];
    30 ////////////////////////////////////////////////////
    31 int fa[N];
    32 int cnt[N];
    33 void init(){
    34     for(int i=0;i<N;i++){
    35         fa[i]=i;
    36         cnt[i]=1;
    37     }
    38 }
    39 int find(int x){
    40     return fa[x]==x?x:fa[x]=find(fa[x]);
    41 }
    42 
    43 //////////////////////////////////////////////////////
    44 bool cmp(Node a,Node b){
    45     return a.cost<b.cost;
    46 }
    47 ////////////////////////////////////////////
    48 int a[M];
    49 int b[M];
    50 int sum[M];
    51 int main()
    52 {
    53     while(scanf("%d%d",&n,&m)==2){
    54         
    55         for(int i=0;i<m;i++){
    56             scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].cost);
    57         
    58         }
    59         sort(node,node+m,cmp);
    60         
    61         for(int i=0;i<m;i++){
    62             b[i]=node[i].cost;
    63         }
    64         
    65         memset(a,0,sizeof(a));
    66         
    67         init();
    68         int ans=0;
    69         for(int i=0;i<m;i++){
    70               int root1=find(node[i].x);
    71             int root2=find(node[i].y);
    72             if(root1==root2) continue;
    73             fa[root1]=root2;
    74             //ans=ans+2*cnt[root1]*cnt[root2];
    75             a[i]=2*cnt[root1]*cnt[root2];
    76             cnt[root2]+=cnt[root1];
    77                     
    78         }
    79         
    80         memset(sum,0,sizeof(sum));
    81         for(int i=m-1;i>=0;i--){
    82             sum[i]=sum[i+1]+a[i];
    83         }
    84         
    85         int q;
    86         scanf("%d",&q);
    87         while(q--){
    88             int t;
    89             scanf("%d",&t);
    90             int w=lower_bound(b,b+m,t)-b;
    91             printf("%d
    ",sum[w]);
    92         }
    93         
    94     }
    95     return 0;
    96 }
    View Code
  • 相关阅读:
    高盛、沃尔玛 题做出来还挂了的吐槽
    amazon师兄debrief
    到所有人家距离之和最短的中点 296. Best Meeting Point
    问问题没人回答的情况怎么办终于有解了
    找名人 277. Find the Celebrity
    数组生存游戏 289. Game of Life
    547. Number of Provinces 省份数量
    428. Serialize and Deserialize Nary Tree 序列化、反序列化n叉树
    alias别名简介和使用
    面试官:线程池执行过程中遇到异常会发生什么,怎样处理? Vincent
  • 原文地址:https://www.cnblogs.com/UniqueColor/p/4815825.html
Copyright © 2011-2022 走看看