• UVa10369 Arctic Network


    基本方法网上有, 这里给出证明.

    网上的证明基本都是瓶颈生成树, 但是并不能说明

    " 任意生成树的第 i 大边不小于最小生成树的第 i 大边 "

    证明:

    考虑做Kruska

    那么一条权值为v的边小于最小生成树里的第k条边

    当且仅当只考虑权值小于等于v的边时图上连通块个数大于n-k

    那么如果v是某个生成树的第k小边

    那小于等于v的边至多把图连成n-k个连通块

    (我是说连通块个数小于等于n-k

    所以v不可能小于最小生成树的第k小边

    (感谢@_rqy)

    证毕.

    证明了这个结论, 代码就很好写了.

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <cmath>
     7 using namespace std;
     8 typedef pair<int, int> P;
     9 const int MAXN = 500 + 10;
    10 
    11 struct _edge
    12 {
    13     int from, to; double cost;
    14     bool operator <(const _edge &rhs) const{
    15         return cost < rhs.cost;
    16     }
    17 };
    18 
    19 vector<_edge> E;
    20 P pos[MAXN];
    21 int N, p, S;
    22 
    23 inline double calcdis(P x, P y)
    24 {return sqrt(pow(fabs(x.first - y.first), 2) + pow(fabs(x.second - y.second), 2));}
    25 
    26 namespace ufs
    27 {
    28     int fa[MAXN];
    29     inline void init(){for(int i = 1; i <= p; i++) fa[i] = i;}
    30     int findfa(int x) {return fa[x] == x ? x : findfa(fa[x]);}
    31     inline void unite(int x, int y) {fa[findfa(x)] = findfa(y);}
    32 }
    33 
    34 vector<double> ans; 
    35 void solve()
    36 {
    37     E.clear();
    38     for(int i = 1; i <= p; i++)
    39         for(int j = i + 1; j <= p; j++)
    40             E.push_back((_edge){i, j, calcdis(pos[i], pos[j])});
    41     sort(E.begin(), E.end());
    42 
    43     using namespace ufs;
    44 
    45     init(); ans.clear(); int cnt = 0;
    46     for(int i = 0, u, v; i < (int) E.size(); i++)
    47     {
    48         u = findfa(E[i].from), v = findfa(E[i].to);
    49         if(u == v) continue;
    50         unite(u, v); cnt++;
    51         ans.push_back(E[i].cost);
    52         if(cnt == p - 1) break;
    53     }
    54     printf("%.2lf
    ", ans[ans.size() - S]);
    55 }
    56 
    57 int main()
    58 {
    59     //freopen("10369.in", "r", stdin);
    60     //freopen("10369.out", "w", stdout);
    61     cin>>N;
    62     while(N--)
    63     {
    64         cin>>S>>p;
    65         for(int i = 1, x, y; i <= p; i++)
    66         {
    67             scanf("%d%d", &x, &y);
    68             pos[i] = P(x, y);
    69         }
    70         solve();
    71     }
    72     return 0;
    73 }

    第N次把kruskal的

    u = findfa(E[i].from), v = findfa(E[i].to);
    

     写成

    u = E[i].from, v = E[i].to;
    

     , 气啊.

  • 相关阅读:
    Mybatis动态SQL
    Mybatis05__#和$的区别
    Mybatis04__输入参数/输出参数
    数据库中的字段和实体类中的字段不一致
    Mybatis中常用注解
    Mybatis03__配置文件简介
    Mybatis实现增、删、改操作时返回主键
    Mybatis04__CURD
    Mybatis02__Mybatis搭建
    lxrunoffline的使用
  • 原文地址:https://www.cnblogs.com/wsmrxc/p/9225364.html
Copyright © 2020-2023  润新知