zoukankan      html  css  js  c++  java
  • poj 2349 Arctic Network(最小生成树的第k大边证明)

    题目链接:

      http://poj.org/problem?id=2349

    题目大意:

      有n个警戒部队,现在要把这n个警戒部队编入一个通信网络,

      有两种方式链接警戒部队:1,用卫星信道可以链接无穷远的部队.

                  2,用信号收发器可以链接周围d米以内的部队.

      现在有s个卫星信道,问d最小是多少时能连接全部的警戒部队?

    解题思路:

      我是用求最小生成树,记录路径长度,对路径长度排序后,第k长的边就是答案,

      但是队友是用最小k度限制生成树,因为我的方法它证明不了,也推翻不了~~~~,

      最后我下去仔细想了想反证法还是可以证明的。

    证明:

      假设:先假设最小生成树的第k大边不是最优解。

      证:现在有一MST,我从中删除了一条第k大的边s,则MST变成了两个联通分支,根据假设存在一条s'<s,可以使两个联通分支连起来变成联通树MST',因为s'<s,则MST'<MST,可得出假设不成立!!!!

     1 #include <cmath>
     2 #include <string>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <iostream>
     6 #include <algorithm>
     7 using namespace std;
     8 
     9 const int maxn = 500;
    10 const int INF = 0x3f3f3f3f;
    11 const double Exp = 1e-10;
    12 
    13 struct point
    14 {
    15     int x, y;
    16     int length(point a)
    17     {
    18         return (a.x - x)*(a.x - x) + (a.y - y)*(a.y - y);
    19     }
    20 };
    21 
    22 int cost[maxn+10][maxn+10], lowc[maxn+10];
    23 int vis[maxn+10], num[maxn+10];
    24 
    25 void init ()
    26 {
    27     for (int i=0; i<maxn+10; i++)
    28         for (int j=0; j<maxn; j++)
    29             cost[i][j] = INF;
    30 }
    31 int prim (int n)
    32 {
    33     int i, j;
    34     memset (vis, 0, sizeof(vis));
    35     vis[0] = 1;
    36     for (i=0; i<n; i++)
    37         lowc[i] = cost[0][i];
    38     for (i=1; i<n; i++)
    39     {
    40         int p, mini = INF;
    41         for (j=0; j<n; j++)
    42             if (!vis[j] && lowc[j] < mini)
    43             {
    44                 p = j;
    45                 mini = lowc[j];
    46             }
    47         vis[p] = 1;
    48         for (j=0; j<n; j++)
    49         {
    50             if (!vis[j])
    51                 lowc[j] = min(lowc[j], cost[p][j]);
    52         }
    53     }
    54 }
    55 
    56 int main ()
    57 {
    58     int n, s, p;
    59     point P[maxn + 10];
    60     scanf ("%d", &n);
    61     while (n --)
    62     {
    63         scanf ("%d %d", &s, &p);
    64         for (int i=0; i<p; i++)
    65         {
    66             scanf ("%d %d", &P[i].x, &P[i].y);
    67             for (int j=0; j<i; j++)
    68                 cost[i][j] = cost[j][i] = P[i].length(P[j]);
    69         }
    70         prim (p);
    71         sort (lowc, lowc+p, greater<int>());
    72         printf ("%.2f
    ", sqrt(lowc[s-1]));
    73     }
    74     return 0;
    75 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    【转】解决在Android设备播放音频与其他应用重音的问题,并监听耳机的控制按钮
    【转】wamp 3.0.6(apache 2.4.23) 403 forbidden 解决办法
    身份证第18位(校验码)的计算方法
    【转】Win10开机密码忘了?教你破解Win10开机密码
    【转】具透 | 你可能不知道,iOS 10 有一个中国「特供」的联网权限功能
    钉钉自定义机器人 发送文本 换行 无效果
    屏蔽右键+f12
    【转】理解WebKit和Chromium: JavaScript引擎简介
    第2章 排序 | 第10节 计数排序练习题 && 基数排序
    图像处理-深入探索插值操作
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4548348.html
Copyright © 2011-2022 走看看