码迷,mamicode.com
首页 > Web开发 > 详细

poj2349 Arctic Network

时间:2017-01-26 19:47:38      阅读:385      评论:0      收藏:0      [点我收藏+]

标签:init   整数   strong   names   ons   res   ack   size   题意   

题意:

某地区共有n座村庄,每座村庄的坐标用一对整数(x, y)表示,现在要在村庄之间建立通讯网络。
通讯工具有两种,分别是需要铺设的普通线路和无线通讯的卫星设备。
只能给k个村庄配备卫星设备,拥有卫星设备的村庄互相间直接通讯。
铺设了线路的村庄之间也可以通讯。但是由于技术原因,两个村庄之间线路长度最多不能超过 d, 否则就会由于信号衰减导致通讯不可靠。要想增大 d 值,则会导致要投入更多的设备(成本)。

已知所有村庄的坐标 (x , y) ,卫星设备的数量 k 。
问:如何分配卫星设备,才能使各个村庄之间能直接或间接的通讯,并且 d 的值最小?求出 d 的最小值。
数据规模:0 <= k <= n<= 500

思路:

只需找到一个最小的d,使得连通支的个数小于等于卫星设备的数目。把整个问题看做一个完全图,只需在该图上求最小生成树,d 的最小值即为第 K 长边。因为:最小生成树中的最长k-1条长边都去掉后,正好将原树分成了k 个连通分支,在每个连通分支上摆一个卫星设备即可。

实现:

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <vector>
  4 #include <algorithm>
  5 #include <cmath>
  6 using namespace std;
  7 struct node
  8 {
  9     int x, y;
 10 };
 11 struct edge
 12 {
 13     int a, b;
 14     double cost;
 15 };
 16 vector<node> ns;
 17 vector<edge> es;
 18 int ran[505];
 19 int par[505];
 20 int t, k, n, x, y;
 21 
 22 int square(int x)
 23 {
 24     return x * x;
 25 }
 26 
 27 bool cmp1(const double & x, const double & y)
 28 {
 29     return x > y;
 30 }
 31 
 32 void init(int n)
 33 {
 34     for (int i = 0; i < n; i++)
 35     {
 36         par[i] = i;
 37         ran[i] = 0;
 38     }
 39 }
 40 int find(int x)
 41 {
 42     if (par[x] == x)
 43         return x;
 44     return par[x] = find(par[x]);
 45 }
 46 void unite(int x, int y)
 47 {
 48     x = find(x);
 49     y = find(y);
 50     if (x == y)
 51         return;
 52     if (ran[x] < ran[y])
 53     {
 54         par[x] = y;
 55     }
 56     else
 57     {
 58         par[y] = x;
 59         if (ran[x] == ran[y])
 60         {
 61             ran[x] ++;
 62         }
 63     }
 64 }
 65 bool same(int x, int y)
 66 {
 67     return find(x) == find(y);
 68 }
 69 
 70 bool cmp(edge a, edge b)
 71 {
 72     return a.cost < b.cost;
 73 }
 74 
 75 void kru(vector<double> & res, int m)
 76 {
 77     init(n);
 78     sort(es.begin(), es.end(), cmp);
 79     for (int i = 0; i < m; i++)
 80     {
 81         if (!same(es[i].a, es[i].b))
 82         {
 83             unite(es[i].a, es[i].b);
 84             res.push_back(es[i].cost);
 85         }
 86     }
 87 }
 88 
 89 int main()
 90 {
 91     cin >> t;
 92     while (t--)
 93     {
 94         ns.clear();
 95         es.clear();
 96         cin >> k >> n;
 97         for (int i = 0; i < n; i++)
 98         {
 99             cin >> x >> y;
100             node tmp;
101             tmp.x = x;
102             tmp.y = y;
103             ns.push_back(tmp);
104         }
105         for (int i = 0; i < ns.size(); i++)
106         {
107             for (int j = i + 1; j < ns.size(); j++)
108             {
109                 edge e;
110                 e.a = i;
111                 e.b = j;
112                 e.cost = sqrt(square(ns[i].x - ns[j].x) + square(ns[i].y - ns[j].y));
113                 es.push_back(e);
114                 e.a = j;
115                 e.b = i;
116                 es.push_back(e);
117             }
118         }
119         vector<double> res;
120         kru(res, es.size());
121         sort(res.begin(), res.end(), cmp1);
122         printf("%.2f\n", res[k - 1]);
123     }
124     return 0;
125 }

 总结:

还有次小生成树、最大生成树等

poj2349 Arctic Network

标签:init   整数   strong   names   ons   res   ack   size   题意   

原文地址:http://www.cnblogs.com/wangyiming/p/6351828.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!