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 }

     总结:

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

  • 相关阅读:
    241. Different Ways to Add Parentheses java solutions
    89. Gray Code java solutions
    367. Valid Perfect Square java solutions
    46. Permutations java solutions
    116. Populating Next Right Pointers in Each Node java solutions
    153. Find Minimum in Rotated Sorted Array java solutions
    判断两颗树是否相同
    求二叉树叶子节点的个数
    求二叉树第k层的结点个数
    将二叉排序树转换成排序的双向链表
  • 原文地址:https://www.cnblogs.com/wangyiming/p/6351828.html
Copyright © 2011-2022 走看看