早上本来就准备挑道简单的做做的,一看这题提交和AC都很多,果断搞起。前面一大堆介绍不用看,其实我也没看懂= =,题意就是给平面上一些点然后求最小生成树,直接上kruskal吧,这题的不相交集我是用数组维护的,以前都是用结构,发现数组方便很多,又优化了一点点,哈哈。做的时候函数命名为distance和STL函数名冲突,一堆编译错误搞的我莫名其妙,查了查才知道。。又坑了一回
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
namespace
{
struct Edge
{
size_t u, v;
double d;
};
double dist(const pair<double, double> &p1, const pair<double, double> &p2)
{
return sqrt(
(p1.first - p2.first) * (p1.first - p2.first)
+ (p1.second - p2.second) * (p1.second - p2.second));
}
bool cmp(Edge *e1, Edge *e2)
{
return e1->d < e2->d;
}
int p[100], rank[100];
int find_set(int x)
{
if (x != p[x])
p[x] = find_set(p[x]);
return p[x];
}
void link(int x, int y)
{
if (rank[x] > rank[y])
p[y] = x;
else
{
p[x] = y;
if (rank[x] == rank[y])
rank[y]++;
}
}
void union_set(int x, int y)
{
link(find_set(x), find_set(y));
}
}
int main()
{
int n, cs = 0;
vector<pair<double, double> > V;
vector<Edge *> E;
while (scanf("%d", &n), n)
{
if (cs)
putchar('\n');
V.clear();
E.clear();
double x, y;
for (int i = 0; i < n; i++)
{
scanf("%lf %lf", &x, &y);
V.push_back(make_pair(x, y));
}
for (size_t i = 0; i < V.size(); i++)
for (size_t j = i + 1; j < V.size(); j++)
{
Edge *e = new Edge();
e->u = i;
e->v = j;
e->d = dist(V[i], V[j]);
E.push_back(e);
}
sort(E.begin(), E.end(), cmp);
memset(rank, 0, sizeof(rank));
for (int i = 0; i < n; i++)
p[i] = i;
double res = 0;
for (size_t i = 0; i < E.size(); i++)
if (find_set(E[i]->u) != find_set(E[i]->v))
{
res += E[i]->d;
union_set(E[i]->u, E[i]->v);
}
printf("Case #%d:\n", ++cs);
printf("The minimal distance is: %.2lf\n", res);
for (size_t i = 0; i < E.size(); i++)
delete E[i];
}
return 0;
}