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

posted on 2016-08-26 19:13  若流芳千古  阅读(274)  评论(0编辑  收藏  举报

导航