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;
}