ZOJ-1203

早上本来就准备挑道简单的做做的,一看这题提交和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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值