POJ1751

注意这道题目对于高速公路两端点城镇的输出顺序没有要求。任意顺序即可,不必要排序。

下面是AC代码: 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=760;
const double eps=1e-10;
int qq,n,m,tot;
struct highway
{
    int to;
    int from;
    double weight;
} pp[maxn*(maxn>>1)];
double x[maxn];
double y[maxn];
int pre[maxn];
bool cmp(highway a,highway b)
{
    return a.weight<b.weight;
}
struct save
{
    int to;
    int from;
} mapp[maxn];
//暂时保存新修建的高速公路
void init()
{
    memset(pp,0,sizeof(pp));
    for(int i=0; i<=n; i++)
        pre[i]=i;
    tot=qq=0;
}
void make_tree()
{
    for(int i=1; i<=n; i++)
        for(int j=i; j<=n; j++)
        {
            pp[qq].from=i;
            pp[qq].to=j;
            pp[qq].weight=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
            ++qq;
        }
}
int finds(int x)
{
    if(x==pre[x])
        return pre[x];
    pre[x]=finds(pre[x]);
    return pre[x];
}
bool cmp2(save a,save b)
{
    if(a.from==b.from)
        return a.to<b.to;
    else
        return a.from<b.from;
}
void kruskal()
{
    sort(pp,pp+qq,cmp);
    int to,from;
    for(int i=0; i<qq; i++)
    {
        to=finds(pp[i].to);
        from=finds(pp[i].from);
        if(to!=from)
        {
            pre[to]=from;
            if(pp[i].weight>eps)//除去已经修建的
            {
                mapp[tot].from=pp[i].from;
                mapp[tot].to=pp[i].to;
                tot++;
            }//新修建的
        }
    }
    sort(mapp,mapp+tot,cmp2);
}
int main()
{
    scanf("%d",&n);
    for(int i=1; i<=n; i++)
    {
        scanf("%lf%lf",&x[i],&y[i]);
    }
    init();
    scanf("%d",&m);
    for(int i=0; i<m; i++)
    {
        scanf("%d%d",&pp[qq].from,&pp[qq].to);
        pp[qq].weight=0;
        qq++;
    }
    make_tree();
    kruskal();
    if(!tot)
    {
        printf("\n");
        return 0;
    }
    for(int i=0;i<tot;i++)
        printf("%d %d\n",mapp[i].from,mapp[i].to);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41658955/article/details/81736222
今日推荐