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

posted @ 2016-01-19 19:19  Armeria  阅读(128)  评论(0编辑  收藏  举报