UVA10369 Arctic Network

Posted mogeko

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA10369 Arctic Network相关的知识,希望对你有一定的参考价值。

传送门

求一棵最小生成树,要求:忽略树上s-1条边的边权后,最大的边最小。

(因为卫星频道是两两互达的,所以想把连接两个联通块之间的边权忽略必须用两个联通块都放置卫星频道。也就是至少要两个)

emmm...其实我本来想的是分层最短路那种动态规划,记录用了几次忽略机会。

假设已经求出答案最小生成树,忽略边权一定是忽略前s-1大的,那么所求即为第s大的边权。

考虑kruskal算法求最小生成树,每次都选最小的边加入...这样其实就保证了每条边都是当前最小的,那第s大一定也是最小的。

证明?在一棵最小生成树上,用一条非树边代替树边,那么第s大的边的边权要么不变要么变大。(来自学姐)

其实就是裸的最小生成树啊w

代码如下

 

技术图片
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define MogeKo qwq
#include<algorithm>
using namespace std;
const int maxn = 1e6;
int t,s,n,cnt,num;
int px[maxn],py[maxn],fa[maxn];

struct node {
    int from,to;
    double val;
    bool operator < (const node & N) const {
        return val < N.val;
    }
} e[maxn];

void add(int a,int b) {
    e[++cnt].from = a;
    e[cnt].to = b;
    e[cnt].val = sqrt( pow(px[a]-px[b],2) + pow(py[a]-py[b],2) );
}

int getfa(int x) {
    if(fa[x] == x)return x;
    else return fa[x] = getfa(fa[x]);
}

double kruskal() {
    for(int i = 1; i <= cnt; i++) {
        int x = getfa(e[i].from);
        int y = getfa(e[i].to);
        if(x == y)continue;
        fa[x] = y;
        num++;
        if(num == n-s)return e[i].val;
    }
}

int main() {
    scanf("%d",&t);
    while(t--) {
        scanf("%d%d",&s,&n);
        cnt = num = 0;
        for(int i = 1; i <= n; i++)
            fa[i] = i;
        for(int i = 1; i <= n; i++)
            scanf("%d%d",&px[i],&py[i]);
        for(int i = 1; i <= n; i++)
            for(int j = i+1; j <= n; j++)
                add(i,j);
        sort(e+1,e+cnt+1);
        printf("%.2lf\n",kruskal());
    }
    return 0;
}
View Code

 

以上是关于UVA10369 Arctic Network的主要内容,如果未能解决你的问题,请参考以下文章

Arctic Network——最小生成树

poj 2349 Arctic Network MST/二分答案

[kuangbin带你飞]专题六 最小生成树 G - Arctic Network

UVA 1267 - Network(贪心DFS)

UVA - 315 Network(tarjan求割点的个数)

[UVA315]Network(tarjan, 求割点)