最小生成树的算法的应用。。。。
一个变量的初始化,再次成为我的绊脚石了,,,,wa了三遍。。
思路不难,,
(1)根据坐标产生边,
(2)求解最小生成树。
代码如下:
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
#define M 5000
double dot[105][2], w[M];
int n, m, u[M], v[M], p[M], r[M];
void print_edge()
{
m = 0;
double dx, dy;
for(int i = 0; i < n; i++)
for(int j = i+1; j < n; j++)
{
dx = dot[i][0]-dot[j][0]; dy = dot[i][1]-dot[j][1];
w[m] = sqrt(dx*dx+dy*dy);
u[m] = i;
v[m] = j;
m++;
}
}
int cmp(const int a, const int b) { return w[a]<w[b]; }
int find(int x) { return p[x]==x?x:find(p[x]); }
double kruskal()
{
double ans = 0;
for(int i = 0; i < n; i++) p[i] = i;
for(int i = 0; i < m; i++) r[i] = i;
sort(r,r+m,cmp);
for(int i = 0; i < m; i++)
{
int e = r[i];
int x = find(u[e]); int y = find(v[e]);
if(x!=y) { ans += w[e]; p[x] = y;}
}
return ans;
}
int main ()
{
int cas, t = 0;
scanf("%d",&cas);
while(t++<cas)
{
scanf("%d",&n);
for(int i = 0; i < n; i++) scanf("%lf%lf",&dot[i][0],&dot[i][1]);
print_edge();
if(t!=1) printf("\n");
printf("%.2lf\n",kruskal());
}
}