HDU 5441

Problem Description
Jack likes to travel around the world, but he doesn’t like to wait. Now, he is traveling in the Undirected Kingdom. There are  n cities and m bidirectional roads connecting the cities. Jack hates waiting too long on the bus, but he can rest at every city. Jack can only stand staying on the bus for a limited time and will go berserk after that. Assuming you know the time it takes to go from one city to another and that the time Jack can stand staying on a bus is x minutes, how many pairs of city (a,b) are there that Jack can travel from city a to b without going berserk?
 

 

Input
The first line contains one integer  T,T5, which represents the number of test case.

For each test case, the first line consists of three integers n,m and q where n20000,m100000,q5000. The Undirected Kingdom has n cities and mbidirectional roads, and there are q queries.

Each of the following m lines consists of three integers a,b and d where a,b{1,...,n} and d100000. It takes Jack d minutes to travel from city a to city b and vice versa.

Then q lines follow. Each of them is a query consisting of an integer x where x is the time limit before Jack goes berserk.

 

 

Output
You should print  q lines for each test case. Each of them contains one integer as the number of pair of cities (a,b) which Jack may travel from a to b within the time limit x.

Note that (a,b) and (b,a) are counted as different pairs and a and b must be different cities.
 

 

Sample Input
1 5 5 3 2 3 6334 1 5 15724 3 5 5705 4 3 12382 1 3 21726 6000 10000 13000
 

 

Sample Output
2 6 12
 

n个城市,m条路,每条路有一个权值w; q个询问每次输入一个数temp,这个人可以走任何权值<=temp的路,
问这个人能走多少对城市 (城市(a,b)和(b,a)算两对); 就是算这个图有多少连通分量(不符合<=temp的边不加入图中),
对于每个连通分量,例如某连通分量有ABC三个城市,则有AB BA AC CA BC CB六个城市对;即有n个城市的连通分量
有n(n-1)个城市对;每个连通分量的城市数就是该集合根节点的秩(代码中的num[]数组); 
计算结果时,每新加入一条边后的结果ans_now,可以由为加入该条边之前的结果ans递推得到;
例如两个连通分量的节点数为 fu ,fv;则join这两个连通分量后的结果ans_now=ans+(fu+fv)*(fu+fv-1)-fu*(fu-1)-fv*(fv-1)=2*fu*fv;


作者:WePlayDirty

  1 #include <iostream>
  2 #include <bits/stdc++.h>
  3 #define MAX 30005
  4 #define foi1(n) for(int i=0;i<n;i++)
  5 using namespace std;
  6 
  7 struct node
  8 {
  9     int u,v;
 10     int w;
 11 }st[1000005];
 12 
 13 struct nod
 14 {
 15     int val;
 16     int id;
 17     friend bool operator<(nod a,nod b)
 18     {
 19         return a.val<b.val;
 20     }
 21 }qu[5005];
 22 
 23 bool cmp(node a,node b)
 24 {
 25     return a.w<b.w;
 26 }
 27 int father[20005];
 28 int num[20005];
 29 void initial(int n)
 30 {
 31     int i;
 32     for(i=1;i<=n;++i)
 33     {
 34         father[i]=i;
 35         num[i]=1;
 36     }
 37 }
 38 int find(int x)
 39 {
 40     int t=x;
 41     while(x!=father[x])
 42         x=father[x];
 43     while(t!=father[t])
 44     {
 45         int temp=t;
 46         t=father[t];
 47         father[temp]=x;
 48     }
 49     return x;
 50 }
 51 void hy(int x,int y)
 52 {
 53     x=find(x);
 54     y=find(y);
 55     if(x!=y)
 56     {
 57         father[y]=x;
 58         num[x]+=num[y];
 59     }
 60 }
 61 int ans[6000];
 62 int main()
 63 {
 64     int T;
 65     scanf("%d",&T);
 66     while(T--)
 67     {
 68         int n,m,q;
 69         scanf("%d%d%d",&n,&m,&q);
 70         int i;
 71         for(i=1;i<=m;++i)
 72         {
 73             scanf("%d%d%d",&st[i].u,&st[i].v,&st[i].w);
 74         }
 75         sort(st+1,st+m+1,cmp);
 76         for(i=1;i<=q;++i)
 77         {
 78             scanf("%d",&qu[i].val);
 79             qu[i].id=i;
 80         }
 81         sort(qu+1,qu+q+1);
 82         int t=1;
 83         initial(n);
 84         int s=0;
 85         for(i=1;i<=q;++i)
 86         {
 87             int temp;
 88             temp=qu[i].val;
 89             while(t<=m&&st[t].w<=temp)
 90             {
 91                 int u=st[t].u;
 92                 int v=st[t].v;
 93                 int x=find(u);
 94                 int y=find(v);
 95                 if(x!=y)
 96                 {
 97                     s+=2*num[x]*num[y];//叠加计算总的
 98                  hy(u,v);
 99                  /*我想的是用插入边之后的根节点对应的num来计算s=num*(num-1),一直WA,可能是因为在插边后根节点不止一个???*/
100                 }
101                 t++;
102             }
103             ans[qu[i].id]=s;
104         }
105         for(i=1;i<=q;++i)
106             printf("%d\n",ans[i]);
107     }
108     return 0;
109 }
View Code

 

转自
https://blog.csdn.net/u013569304/article/details/48475251

全部评论

相关推荐

12-08 07:42
门头沟学院 Java
27届末九,由于是女生,身边人几乎没有就业导向的,自学只能跟着网课,没人指导,很迷茫。下图是我目前的简历,不知道有需要修改的地方吗?求拷打。下面是目前的学习情况:目前算法过完了一遍力扣100和代码随想录,不过不是很熟,面经看了小林coding、JavaGuide,有一些没用过的技术看得不是很明白,掌握得不是很扎实。再加上常年跟黑马网课听思路,真正自己动手写代码的时间很少,这让我一直不敢投简历,总觉得内里空虚。项目没准备好面试相关的问题,简历上相应的考点不熟。如此种种。。。看到很多很多学长学姐大佬们的面经,愈发觉得面试可怕,自己没准备好,总担心自己是不是无望后端开发了。看到牛客很多同届以及更小一届的同学都找到实习了,很希望自己也能找到实习。而自己又好像摸不到后端学习的门路,只能不断赞叹黑马虎哥写的代码真优雅!微服务架构实在巧妙!消息队列、redis、sentinel、nacos、mybatisplus等等的引入都会让我赞叹这些工具的设计者的巧思,以及包括但不限于Java语言的优雅。然而只是停留在了解的程度,并不熟练。我是很希望能够继续深入探索这些知识的,只不过有一大部分时间都花在学校课程上了。我感觉我被困住了,我一方面必须保证我能够有个不错的学业分使我能有我几乎不想选择的读研退路(还有个原因是复习不全我会焦虑考试挂科,因此我会做好全面的准备,而这一步很费时间),一方面在B站学习各种网课,一方面得考虑提升自己并不扎实的算法基础,另一方面还得准备八股面经。这让我有点苦恼,我好像没那么多时间,因为绝大部分时间都花在了复习学校科目中了。我好像处处用时间,但收效甚微。想问问各位大佬是怎么平衡时间的呢?算法、项目和八股是怎么准备的呢?有什么高效的方法吗?谢谢您们花时间阅读我的稿件!
菜菜狗🐶:大胆投,我当时也是害怕面试,投多了发现根本约不到面🤡
投递哔哩哔哩等公司6个岗位
点赞 评论 收藏
分享
12-20 11:26
复旦大学 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务