zoukankan      html  css  js  c++  java
  • zoj 1203 最小生成树—kruscal算法

    链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1203

    题意:给出n个城市的坐标,计算连接这n个城市所需路线总长度的最小值。

    思路:先求出每两个城市间的距离,也就是边权,然后用kruscal来求最小生成树,得出最小值。

    注意输出格式,要求每两个输出之间要有一个空行。但是最后的一个输出后面不能有空行,所以判断是不是第一个输出,不是的话,先打一个空行。

    一开始写wa了,找了很久错误没找出来,后面发现是cmp()函数写的有问题。

    一开始我是直接把上次写的kruscal()示例程序中的cmp()函数粘贴了过来。没想问题,结果,呵呵。

    好吧,这种比较函数我确实不是很懂,虽然也写过很多次。。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #include<string>
    #include<cmath>
    #include<map>
    #include<algorithm>
    using namespace std;
    
    const int maxn=100;
    const int maxm=5000;
    int n,m;
    double sumw;
    double X[maxn],Y[maxn];
    struct Edge
    {
        int u,v;
        double w;
    }edges[maxm];
    class set
    {
    public:
        void makeset(int k)
        {
            for(int i=0; i<k; i++)
            {
                father[i]=i;
                rank[i]=1;
            }
        }
        int findset(int x)
        {
            if(x!=father[x])
                father[x]=findset(father[x]);
            return father[x];
        }
        void unionset(int x,int y)
        {
            x=findset(x);
            y=findset(y);
            if(x==y)  return;
            if(rank[x]>rank[y])
            {
                father[y]=x;
                rank[x]+=rank[y];
            }
            else
            {
                father[x]=y;
                rank[y]+=rank[x];
            }
        }
    private:
    
        int father[maxn];
        int rank[maxn];
    }ufs;
    
    int cmp(const void* a,const void* b)
    {
        Edge aa=*(const Edge*)a, bb=*(const Edge*)b;
        if(aa.w>bb.w) return 1;
        else return -1;
       // return aa.w-bb.w;
    }
    void kruscal()
    {
        int num=0,u,v;
        sumw=0.0;
        ufs.makeset(n);
        for(int i=0;i<m;i++)
        {
            u=edges[i].u;v=edges[i].v;
            if(ufs.findset(u)!=ufs.findset(v))
            {
               num++;
               sumw+=edges[i].w;
               ufs.unionset(u,v);
            }
            if(num>=n-1) break;
        }
    }
    int main()
    {
        int kase=1;
        double d;
        while(scanf("%d",&n) && n)
        {
            for(int i=0;i<n;i++)
                scanf("%lf%lf",&X[i],&Y[i]);
            int mi=0;//边的序号
            for(int i=0;i<n;i++)
                for(int j=i+1;j<n;j++)
                {
                    d=sqrt((X[i]-X[j])*(X[i]-X[j])+(Y[i]-Y[j])*(Y[i]-Y[j]));
                    edges[mi].u=i;edges[mi].v=j;edges[mi].w=d;
                    mi++;
                }
            m=mi;
            qsort(edges,m,sizeof(edges[0]),cmp);
            kruscal();
            if(kase>1) printf("\n");
            printf("Case #%d:\n",kase++);
            printf("The minimal distance is: %.2lf\n",sumw);
        }
        return 0;
    }
  • 相关阅读:
    无人转会申请
    【Alpha】“北航社团帮”小程序v1.0项目展示
    【Alpha】“北航社团帮”小程序v1.0测试报告
    【Alpha】“北航社团帮”小程序v1.0发布声明
    【Alpha】Scrum meeting 10
    编译原理:文法和语言总结与梳理
    编译原理:语法树,短语,直接短语,句柄
    编译原理:理解文法和语文
    编译原理:了解编译原理
    MySQL8版本的安装与卸载教程
  • 原文地址:https://www.cnblogs.com/54zyq/p/3110166.html
Copyright © 2011-2022 走看看