HDU4463Outlets(最小生成树)

HDU4463Outlets(最小生成树)

HDU4463Outlets

题目大意: 
需要新建一个mall,里面有很多的商店,希望修最短的路,使得里面的店联通,可以通过别的店间接的联通,但是有规定两家店一定要直接的联通。求在这样的条件下的最短的路径。

解题思路: 
最小生成树,只是前提是先要使得要求的两个结点先联通。

代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;

const int maxn = 55;

int N, P, Q;
int X[maxn], Y[maxn], p[maxn];
struct edge{
    int u, v;
    double d;
}e[maxn * maxn];

double dist (const int u, const int v) {
    return sqrt((X[u] - X[v]) * (X[u] - X[v]) + (Y[u] - Y[v]) * (Y[u] - Y[v]));
}

int cmp (const edge& a, const edge& b) {
    return a.d < b.d;
}

void init () {  
    for (int i = 1; i <= N; i++)
        p[i] = i;
}

int getParent(int x) {
    return x == p[x] ? x : p[x] = getParent(p[x]);
}

int main () {

    while (scanf ("%d", &N) && N) {

        scanf ("%d%d", &P, &Q);
        for (int i = 1; i <= N; i++)
            scanf("%d%d", &X[i], &Y[i]);

        int cnt = 0;
        for (int i = 1; i <= N; i++)
            for (int j = i + 1; j <= N; j++) {
                e[cnt].u = i;
                e[cnt].v = j;
                e[cnt].d = dist(i, j);
                cnt++;
            }

        sort(e, e + cnt, cmp);
        init();

        double ans = dist(P, Q);
        int count = 1;
        p[P] = Q;

        for (int i = 0; i < cnt; i++) {

            int p1 = getParent(e[i].u);
            int p2 = getParent(e[i].v);
            if (p1 != p2) {
                ans += e[i].d;
                p[p1] = p2;
                count++;
            }
            if (count == N - 1)
                break;
        }

        printf ("%.2lf\n", ans);
    }
    return 0;
}

你可能感兴趣的:(HDU4463Outlets(最小生成树))