hdu_4463(最小生成树)
hdu_4463(最小生成树)
标签: 并查集
- 题意: 求一个必须包含一条路径的最小生成树
- 题解: 把那条边初始化成0 保证这条边一定会被选
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 50;
double x[N],y[N];
struct Edge{
int from;
int to;
double dis;
bool operator <(const Edge e) const
{
return dis<e.dis;
}
}edge[N*N];
double aabs(double a)
{
if(a<0) return -a;
else return a;
}
int fa[N];
int Ecnt;
int Getfa(int x){
return (fa[x]==x)?x:fa[x] = Getfa(fa[x]);
}
int main()
{
int n;
while(~scanf("%d",&n),n)
{
Ecnt = 0;
int s,t;
scanf("%d%d",&s,&t);
for(int i = 1; i <= n; i++){
scanf("%lf %lf",&x[i],&y[i]);
}
double tm;
for(int i = 1; i <= n; i++){
for(int j = 1; j < i; j++){
if(i==s&&j==t) {
edge[Ecnt].from = i;
edge[Ecnt].to = j;
edge[Ecnt++].dis = 0;
tm = sqrt(aabs(x[i]-x[j])*aabs(x[i]-x[j])+aabs(y[i]-y[j])*aabs(y[i]-y[j]));
edge[Ecnt].from = j;
edge[Ecnt].to = i;
edge[Ecnt++].dis = 0;
continue;
}
else if(i==t&&j==s){
edge[Ecnt].from = i;
edge[Ecnt].to = j;
edge[Ecnt++].dis = 0;
tm = sqrt(aabs(x[i]-x[j])*aabs(x[i]-x[j])+aabs(y[i]-y[j])*aabs(y[i]-y[j]));
edge[Ecnt].from = j;
edge[Ecnt].to = i;
edge[Ecnt++].dis = 0;
continue;
}
edge[Ecnt].from = i;
edge[Ecnt].to = j;
edge[Ecnt++].dis = sqrt(aabs(x[i]-x[j])*aabs(x[i]-x[j])+aabs(y[i]-y[j])*aabs(y[i]-y[j]));
edge[Ecnt].from = j;
edge[Ecnt].to = i;
edge[Ecnt++].dis = sqrt(aabs(x[i]-x[j])*aabs(x[i]-x[j])+aabs(y[i]-y[j])*aabs(y[i]-y[j]));
}
}
sort(edge,edge+Ecnt);
double ans = 0;
for(int i = 1; i <= n ;i++) fa[i] = i;
int cnt = 0;
for(int i = 0; i < Ecnt; i++){
int X = Getfa(edge[i].from);
int Y = Getfa(edge[i].to);
if(X!=Y){
cnt++;
ans += edge[i].dis;
fa[Y] = X;
if(cnt==n-1){
break;
}
}
}
ans+=tm;
printf("%.2lf\n",ans);
}
return 0;
}