洛谷P1991 无线通讯网【最小生成树】
题目:https://www.luogu.org/problemnew/show/P1991
题意:有p个点的坐标,可以有s个点使得这s个点之间可以无限制通信。
要使所有点之间两两有通信的路径(可以是间接的),其中最长的一段通信路径是多长。
思路:最近都不好好看题。上一题没看清-1,这一题没看清精确到小数点两位,在干吗啊。
首先建图,然后找最小生成树里第p-s大的路径长度。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<map> 4 #include<set> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<cmath> 9 #include<stack> 10 #include<queue> 11 #include<iostream> 12 13 #define inf 0x3f3f3f3f 14 using namespace std; 15 typedef long long LL; 16 typedef pair<int, int> pr; 17 18 int s, n; 19 const int maxn = 505; 20 struct node{ 21 int x, y; 22 }nodes[maxn]; 23 double g[maxn][maxn]; 24 25 double dist(int i, int j) 26 { 27 return sqrt((nodes[i].x - nodes[j].x) * (nodes[i].x - nodes[j].x) + (nodes[i].y - nodes[j].y) * (nodes[i].y - nodes[j].y)); 28 } 29 30 bool vis[maxn]; 31 double d[maxn]; 32 vector<double>ans; 33 void prim(int x) 34 { 35 memset(d, 0x3f, sizeof(d)); 36 d[x] = 0; 37 vis[x] = true; 38 for(int i = 1; i <= n; i++){ 39 d[i] = g[x][i]; 40 } 41 42 for(int t = 1; t < n; t++){ 43 double min = inf; 44 int minid; 45 for(int i = 1; i <= n; i++){ 46 if(!vis[i] && d[i] < min){ 47 min = d[i]; 48 minid = i; 49 } 50 } 51 vis[minid] = true; 52 ans.push_back(min); 53 for(int i = 1; i <= n; i++){ 54 if(d[i] > g[minid][i]){ 55 d[i] = g[minid][i]; 56 } 57 } 58 } 59 } 60 61 int main() 62 { 63 scanf("%d%d", &s, &n); 64 for(int i = 1; i <= n; i++){ 65 scanf("%d%d", &nodes[i].x, &nodes[i].y); 66 } 67 for(int i = 1; i <= n; i++){ 68 for(int j = i + 1; j <= n; j++){ 69 g[i][j] = g[j][i] = dist(i, j); 70 //printf("%lf\n", g[i][j]); 71 } 72 } 73 74 prim(1); 75 sort(ans.begin(), ans.end()); 76 printf("%.2lf\n", ans[n - s - 1]); 77 return 0; 78 }