zoukankan      html  css  js  c++  java
  • poj2349 Arctic Network

    题意:

    某地区共有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
    ", res[k - 1]);
    123     }
    124     return 0;
    125 }

     总结:

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

  • 相关阅读:
    BZOJ3578:GTY的人类基因组计划2(集合hash,STL)
    【BZOJ 1022】 [SHOI2008]小约翰的游戏John
    【BZOJ 1295】 [SCOI2009]最长距离
    【BZOJ 1103】 [POI2007]大都市meg
    【BZOJ 3172】 [Tjoi2013]单词
    【BZOJ 1067】 [SCOI2007]降雨量
    【BZOJ 1491】 [NOI2007]社交网络
    【BZOJ 1087】[SCOI2005]互不侵犯King
    【BZOJ 1009】 [HNOI2008]GT考试
    【BZOJ 1053】[HAOI2007]反素数ant
  • 原文地址:https://www.cnblogs.com/wangyiming/p/6351828.html
Copyright © 2011-2022 走看看