Count The Pairs

来源:互联网 发布:淘宝买东西优惠 编辑:程序博客网 时间:2024/06/07 18:56

  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 10 1 231233 30 1 20 2 41 2 550 2345
Sample Output
22066440

题意:问我们路径上的最大边 大于等于 t 的有多少对点。也就是说两点之间的路径上,最大的边是大于等于 t 的,有多少个这样的两个点。

思路:通过最小生成树的构造,我们明白,每次拿的边都是剩下的最小边,是已经生成树的最大边,也就是说,以这条边为最大边的点是 左边的数量*右边的数量*2(1->2,2->1不同)。所以我们需要记录下来,这两个家族的数量。就好了。

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;/*最小生成树,主要是找点,不是边,所以不用存下来图,只需要边的长度就好了这个边我也是蒙了一阵,不知所措,如果直接看长度的话,那直接TLE*/int pre[10010];int num[10010];int ans[500010];int sum[500010];int b[500010];int n,m;struct edge{    int u,v,w;}Edge[500010];int cmp(edge a,edge b){    return a.w<b.w;}int find_root(int x){    return pre[x]==x?x:pre[x]=find_root(pre[x]);}int main(){   while(~scanf("%d %d",&n,&m))   {       memset(ans,0,sizeof(ans));       memset(sum,0,sizeof(sum));       memset(b,0,sizeof(b));       for(int i=0;i<n;i++)         pre[i]=i,num[i]=1;//每个点都是孤立的       for(int i=0;i<m;i++)       {           scanf("%d %d %d",&Edge[i].u,&Edge[i].v,&Edge[i].w);       }       sort(Edge,Edge+m,cmp);       for(int i=0;i<m;i++)       {           b[i]=Edge[i].w;//为后面权值好查找到哪一个i           int x,y,rx,ry;           x=Edge[i].u,y=Edge[i].v;           rx=find_root(x),ry=find_root(y);           if(rx!=ry)           {               pre[ry]=rx;               ans[i]=num[rx]*num[ry]*2;//说明这以第i条边为最长的边,有这些种情况               num[rx]+=num[ry];//家族合并           }       }       for(int i=m-1;i>=0;i--)         sum[i]=ans[i]+sum[i+1];//对应的这条边,合并答案       int k;       scanf("%d",&k);       for(int i=0;i<k;i++)       {           int q;           scanf("%d",&q);           int id = lower_bound(b,b+m,q) - b;//寻找b[i]大于等于q的下标           if(id >= m)printf("0\n");//超界,不存在。           else           {                printf("%d\n",sum[id]);           }       }   }    return 0;}