Hackerrank--Savita And Friends(最小直径生成树MDST)

题目链接

After completing her final semester, Savita is back home. She is excited to meet all her friends. Her N friends live in different houses spread across the city.

There are M roads connecting the houses. The road network formed is connected and does not contain self loops and multiple roads between same pair of houses. Savita and Friends decide to meet.

Savita wants to choose a point(not necessarily an integer) P on the road numbered K, such that, the maximum of dist(i) for all 1≤i≤N is minimised, 
where dist(i) is the shortest distance between the i‘th friend and P.

If K‘th road connects friend A and friend B you should print distance of chosen point from A. Also, print the max(dist(i)) for all 1≤i≤N. If there is more than one solution, print the one in which the point P is closest to A.

Note:

  • Use scanf/printf instead of cin/cout. Large input files.
  • Order of A and B as given in the input must be maintained. If P is at a distance of 8 from A and 2 from B, you should print 8 and not 2.

Input Format
First line contain T, the number of testcases. 
T testcases follow. 
First Line of each testcase contains 3 space separated integers N,M,K . 
Next M lines contain description of the ith road : three space separated integers A,B,C, where C is the length of road connecting A and B.

Output Format
For each testcase, print two space separated values in one line. The first value is the distance of P from the point A and the second value is the maximum of all the possible shortest paths between P and all of Savita‘s and her friends‘ houses. Round both answers to 5 decimal digits and print exactly 5 digits after the decimal point.

Constraints
1≤T≤10 
2≤N,M≤105 
N−1≤M≤N∗(N−1)/2 
1≤A,B≤N 
1≤C≤109 
1≤K≤M

Sample Input

2
2 1 1
1 2 10
4 4 1
1 2 10
2 3 10
3 4 1
4 1 5

Sample Output

5.00000 5.00000
2.00000 8.00000

Explanation

First testcase: 
As K = 1, they will meet at the point P on the road that connects friend 1 with friend 2. If we choose mid point then distance for both of them will be 5. In any other position the maximum of distance will be more than 5.

Second testcase: 
As K = 1, they will meet at a point P on the road connecting friend 1 and friend 2. If we choose point at a distance of 2 from friend 1: Friend

1 will have to travel distance 2. 
Friend 2 will have to travel distance 8. 
Friend 3 will have to travel distance 8. 
Friend 4 will have to travel distance 7. 
So, the maximum will be 8. 
In any other position of point choosen, the maximum distance will be more than 8.

Timelimits 

Timelimits for this problem is 2 times the environment limit.

 1 #include <queue>
 2 #include <cstdio>
 3 #include <iomanip>
 4 #include <vector>
 5 #include <cstring>
 6 #include <iostream>
 7 #include <algorithm>
 8 using namespace std;
 9
10 #define X first
11 #define Y second
12 typedef long long LL;
13 typedef pair<LL , LL> pii;
14 const LL INF = 1e18;
15 const int MAX_N = 100050;
16 vector<pii> G[MAX_N];
17 LL d1[MAX_N], d2[MAX_N];
18 bool done[MAX_N];
19 int n, m;
20
21 void dijkstra(int s, LL *d) {
22     memset(done, false, sizeof(done));
23     priority_queue<pii, vector<pii>, greater<pii> > Q;
24     for (int i = 1; i <= n; i++) d[i] = INF;
25     Q.push(pii(0, s));
26     d[s] = 0;
27
28     while (!Q.empty()) {
29         int u = Q.top().Y; Q.pop();
30         done[u] = true;
31
32         for (int i = 0; i < G[u].size(); i++) {
33             int v = G[u][i].X, w = G[u][i].Y;
34             if (d[v] > d[u] + w) {
35                 d[v]  = d[u] + w;
36                 Q.push(pii(d[v], v));
37             }
38         }
39     }
40 }
41
42 int main(void) {
43     //ios::sync_with_stdio(false);
44     int T;
45     scanf("%d", &T);
46     //cin >> T;
47     while (T--) {
48         int k, kth, s1, s2;
49         //cin >> n >> m >> k;
50         scanf("%d %d %d", &n, &m, &k);
51         for (int i = 1; i <= n; i++) G[i].clear();
52         for (int i = 1; i <= m; i++) {
53             int a, b, c;
54             scanf("%d %d %d", &a, &b, &c);
55             //cin >> a >> b >> c;
56             G[a].push_back(pii(b, c));
57             G[b].push_back(pii(a, c));
58             if (i == k) s1 = a, s2 = b, kth = c;
59         }
60         dijkstra(s1, d1);
61         dijkstra(s2, d2);
62         //for (int i = 1; i <= n; i++) cerr << d1[i] << endl;
63
64         vector<pii> A;
65         for (int i = 1; i <= n; i++) A.push_back(pii(d1[i], d2[i]));
66         sort(A.begin(), A.end());
67         vector<pii> B;
68         LL fst = -1, snd = -1;
69         for (int i = n - 1; i >= 0; i--) {
70             if (A[i].X <= fst && A[i].Y <= snd) continue;
71             fst = A[i].X, snd = A[i].Y;
72             B.push_back(A[i]);
73         }
74         double ans, p;
75         int kk = B.size();
76         if (B[0].X < B[kk - 1].Y) ans = B[0].X, p = 0.0;
77         else ans = B[kk - 1].Y, p = kth + 0.0;
78         for (int i = 0; i < kk - 1; i++) {
79             double tmp = (B[i].Y - B[i + 1].X + kth) * 0.5;
80             double val = B[i + 1].X + tmp;
81             if (ans > val) ans = val, p = tmp;
82             else if (ans == val && p > tmp) p = tmp;
83         }
84         printf("%.5f %.5f\n", p, ans);
85     }
86     return 0;
87 }
时间: 2024-10-19 10:39:47

Hackerrank--Savita And Friends(最小直径生成树MDST)的相关文章

BZOJ2180: 最小直径生成树

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2180 2180: 最小直径生成树 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 195  Solved: 93[Submit][Status][Discuss] Description 输入一个无向图G=(V,E),W(a,b)表示边(a,b)之间的长度,求一棵生成树T,使得T的直径最小.树的直径即树的最长链,即树上距离最远的两点之间路径

POJ 1861 ——Network——————【最小瓶颈生成树】

Network Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 15268   Accepted: 5987   Special Judge Description Andrew is working as system administrator and is planning to establish a new network in his company. There will be N hubs in the c

HDU5697 刷题计划 dp+最小乘积生成树

分析:就是不断递归寻找靠近边界的最优解 学习博客(必须先看这个): 1:http://www.cnblogs.com/autsky-jadek/p/3959446.html 2:http://blog.csdn.net/u013849646/article/details/51524748 注:这里用的最小乘积生成树的思想,和dp结合 每次找满足条件的最优的点,只不过BZOJ裸题的满足条件是形成一棵树 这个题是大于m,生成树借用最小生成树进行求解最优,大于m用dp进行求解最优 #include

算法笔记_164:算法提高 最小方差生成树(Java)

目录 1 问题描述 2 解决方案   1 问题描述 问题描述 给定带权无向图,求出一颗方差最小的生成树. 输入格式 输入多组测试数据.第一行为N,M,依次是点数和边数.接下来M行,每行三个整数U,V,W,代表连接U,V的边,和权值W.保证图连通.n=m=0标志着测试文件的结束. 输出格式 对于每组数据,输出最小方差,四舍五入到0.01.输出格式按照样例. 样例输入 4 51 2 12 3 23 4 24 1 12 4 34 61 2 12 3 23 4 34 1 12 4 31 3 30 0 样

bzoj2395[Balkan 2011]Timeismoney最小乘积生成树

所谓最小乘积生成树,即对于一个无向连通图的每一条边均有两个权值xi,yi,在图中找一颗生成树,使得Σxi*Σyi取最小值. 直接处理问题较为棘手,但每条边的权值可以描述为一个二元组(xi,yi),这也就不难想到将生成树转化为平面内的点,x代表Σxi,y代表Σyi(注意这里的xi,yi指的是在生成树中的边的权值),那么问题就变成了在平面内找一个点使得x*y最小,那么显然这个点是在下凸壳上的. 因此可以首先找出两个一定在凸包上的点,例如A(minx,y),B(miny,x),在直线AB下方找一个在凸

【最小瓶颈生成树】【最小生成树】【kruscal】bzoj1083 [SCOI2005]繁忙的都市

本意是求最小瓶颈生成树,但是我们可以证明:最小生成树也是最小瓶颈生成树(其实我不会).数据范围很小,暴力kruscal即可. 1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 struct Edge{int u,v,w;void Read(){scanf("%d%d%d",&u,&v,&w);}}edges[10001]; 5 bool operator &

(最小生成树/最小瓶颈生成树) 2017武汉现场赛 - Wifi Relay

题意: n个无线AP,有xy坐标属性,现在n个无线AP要桥接在一起不能断开连接,现在要求无线AP无线网络的覆盖半径最小是多少 分析: 看起来是像是最小生成树,这里是是求生成树中最长的边最短,就是最小瓶颈生成树. 可以证明最小瓶颈生成树就是最小生成树,详细看刘汝佳<算法入门经典训练指南>343页. 当时现场的时候,想试试最小生成树了,结果以为n方复杂度过不去,就没写,现在想起来,真是坑哦. 这题n有10000,所以不能直接建邻接矩阵,而是采用动态计算距离就行了. 比赛结束了随便一写就A了...

poj 3522 Slim Span 最大边减最小边最小的生成树

枚举最小边进行kruskal. #include <cstdio> #include <algorithm> using namespace std; #define maxn 120 #define maxm 10000 struct edge { int u,v,w; }e[maxm]; int p[maxn],n,m; int find(int x) { if(x==p[x]) return x; return p[x]=find(p[x]); } void link(int

POJ2728 最小比率生成树/0-1分数规划/二分/迭代(迭代不会)

用01分数规划 + prime + 二分 竟然2950MS惊险的过了QAQ 前提是在TLE了好几次下过的 = = 题目意思:有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,只要两个村庄之间有一条路即可,建造水管距离为坐标之间的欧几里德距离,费用为海拔之差,现在要求方案使得费用与距离的比值最小,很显然,这个题目是要求一棵最优比率生成树. 解题思路: 对答案进行二分,当把代进去的答案拿来算最小生成树的时候,一旦总路径长度为0,就是需要的答案. 0-1规划是啥? 概念有带权图G, 对于图中每条