BZOJ 1626 - 最小生成树
最小生成树的裸题咯…
但是在边的编号上还是出了点问题… 以后直接上\(n×n\),不虚。。
// BZOJ 1626
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=1000+5, M=N*N;
#define rep(i,a,b) for (int i=a; i<=b; i++)
#define read(x) scanf("%d", &x)
#define fill(a,x) memset(a, x, sizeof(a))
struct Edge{
int from, to;
double len;
bool operator < (const Edge x) const { return len < x.len; }
} e[M];
int x[N], y[N], fa[N], n, m, u, v;
double ans = 0;
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
double sqr(double x) { return x*x; }
double calc(int u, int v) { return sqrt(sqr(x[u]-x[v])+sqr(y[u]-y[v])); }
int main()
{
read(n); read(m);
rep(i,1,n) read(x[i]), read(y[i]);
int tot = 1;
rep(i,1,n) rep(j,1,i) {
Edge &t = e[tot];
t.len = calc(i, j);
t.from = i, t.to = j;
tot++;
}
tot--;
rep(i,1,m) {
read(u), read(v);
if (u < v) swap(u, v);
e[u*(u-1)/2+v].len = 0;
}
sort(e+1, e+tot+1);
rep(i,1,n) fa[i] = i;
rep(i,1,tot) {
int fx = find(e[i].from), fy = find(e[i].to);
if (fx != fy) {
ans += e[i].len;
fa[fx] = fy;
}
}
printf("%.2lf\n", ans);
return 0;
}