注意这道题目对于高速公路两端点城镇的输出顺序没有要求。任意顺序即可,不必要排序。
下面是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;
}