链接: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;
}

 

 posted on 2013-05-31 12:59  ∑求和  阅读(231)  评论(0编辑  收藏  举报