zoukankan      html  css  js  c++  java
  • 【最小生成树-第k大边】Arctic Network POJ

    Arctic Network POJ - 2349

    相似题目:POJ 2253 Frogger

    题意:

    给定(p)个哨所的坐标,可任意使其中(s)个拥有卫星通讯功能。任意两个具有卫星通讯功能的哨所视为连通。在剩下的哨所之间建立无线电路径,路径的花费(D)为哨所之间的距离。求能使所有哨所连通的最小的(D)

    思路:

    如果忽略卫星通讯这个条件,题目所求的明显是最小生成树的最大边。

    加上卫星通讯这个条件,就相当于可以使最小生成树中的任意(s-1)条边免费,再在剩下不免费的边中找出花费最大的那一条。

    结合题意,将最小生成树的所有边从大到小排序,使前(s-1)条边免费,那么第(s)条边的花费就是答案了。

    差点就1A了,但是因为把500*500算成了25000导致数组开小了而RE了一发……

    int fa[maxn];
    int tmp1[maxn], tmp2[maxn];
    int u[maxn], v[maxn];
    double w[maxn];
    double edge[maxn];
    int n, m, m2, k;
    
    struct node {
        double x, y;
    }N[maxn];
    
    int find(int x) { 
        return fa[x] == x ? x : fa[x] = find(fa[x]); 
    }
    bool cmp1(int i, int j) {
        return w[i] < w[j];
    }
    
    bool cmp2(int i, int j) {
        return edge[i] > edge[j];
    }
    
    double count(node t1, node t2) {
        double dx = t1.x - t2.x;
        double dy = t1.y - t2.y;
        return sqrt(dx * dx + dy * dy);
    }
    
    double solve() {
       // double ans = 0;
        for (int i = 0; i < maxn; i++) fa[i] = i;
        for (int i = 0; i < m; i++) tmp1[i] = i;
        for (int i = 0; i < m; i++) tmp2[i] = i;
        sort(tmp1, tmp1 + m, cmp1);
        //板子内容,将备选的所有边从小到大排序,以便计算最小生成树
        for (int i = 0; i < m; i++) {
            int e = tmp1[i];
            int from = find(u[e]);
            int to = find(v[e]);
            if (from != to) {
               // ans += w[e];
                edge[m2++] = w[e];
                //记录最小生成树中边的花费
                fa[from] = to;
            }
        }
        sort(tmp2, tmp2 + m2, cmp2);
        //将最小生成树中的所有边从大到小排序,只将结果以下标形式保存在tmp2中
        return edge[tmp2[k-1]];
        //注意tmp2下标从0开始,第x大的边下标为x-1
        //题目给定的卫星信道不是边,是拥有该功能的点的数量
        //k个卫星信道形成k-1条边,所以要求的是树中第k大条边
       // return ans;
    }
    
    int main()
    {
        //ios::sync_with_stdio(false);
        int t; cin >> t; while (t--) {
            m = 0;
            m2 = 0;
            cin >> k >> n;
            for (int i = 1; i <= n; i++) {
                cin >> N[i].x >> N[i].y;
                for (int j = i-1 ; j >= 1; j--) {
                    double tp = count(N[i], N[j]);
                    u[m] = i; v[m] = j; w[m] = tp; m++;
                    u[m] = j; v[m] = i; w[m] = tp; m++;
                }
            }
            printf("%.2f
    ", solve());
        }
        return 0;
    }
    
  • 相关阅读:
    Recommended Books for Algo Trading in 2020
    Market Making is simpler than you think!
    Top Crypto Market Makers of 2020
    Top Crypto Market Makers, Rated and Reviewed
    爬取伯乐在线文章(五)itemloader
    爬取伯乐在线文章(四)将爬取结果保存到MySQL
    爬取伯乐在线文章(三)爬取所有页面的文章
    爬取伯乐在线文章(二)通过xpath提取源文件中需要的内容
    爬取伯乐在线文章(一)
    爬虫去重策略
  • 原文地址:https://www.cnblogs.com/streamazure/p/13503422.html
Copyright © 2011-2022 走看看