弗拉塔托邦这个岛国是完全平坦的。不幸的是,弗拉塔托市的公共高速公路系统非常差。弗拉托皮亚政府意识到这一问题,已经修建了一些连接一些最重要城镇的公路。然而,仍然有一些城镇你不能通过公路到达。有必要修建更多的公路,这样就可以在两个城镇之间行驶而不离开公路系统。
弗拉托派城镇的编号是从1到N,而I镇的位置是由笛卡尔坐标(xi,yi)确定的。每条公路连接两个城镇。所有公路(包括原来的公路和将要修建的公路)都沿着直线行驶,因此它们的长度等于城镇之间的笛卡尔距离。所有的公路都可以双向使用。公路可以自由交叉,但司机只能在两条公路尽头的一个城镇的高速公路之间切换。
弗拉托派政府希望将修建新公路的成本降到最低。然而,他们想要保证每个城镇都是高速公路-从其他城镇都可以到达。由于弗拉托邦是如此平坦,一条公路的成本总是与其长度成正比。因此,最便宜的公路系统将是一个最大限度地减少公路总长度的公路系统。
输入
输入由两部分组成。第一部分描述全国所有城镇,第二部分描述所有已经建成的公路。
输入文件的第一行包含一个整数N(1<=N<=750),表示城镇数。下一个N行分别包含两个整数,xi和yi用空格分隔。这些值给出了i的坐标。TH城镇(我从1到N)。坐标的绝对值不大于10000。每个城镇都有一个独特的位置。
下一行包含一个整数M(0<=M<=1000),表示现有公路的数量。下一个M行每一行都包含一对由空格分隔的整数。这两个整数给出了一对已经通过公路连接的城镇编号。每一对城镇最多有一条公路相连。
输出量
为每一条新建公路写一条单线,以便以尽可能短的新公路总长将所有城镇连接起来。每条公路都应该打印出这条公路连接的城镇编号,用一个空间隔开。
如果不需要新建公路(所有城镇都已连接),则应该创建输出文件,但它应该是空的。
样本输入
9 1 5 0 0 3 2 4 5 5 1 0 4 5 2 1 2 5 3 3 1 3 9 7 1 2
样本输出
1 6 3 7 4 9 5 7 8 3
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<vector>
#include<cmath>
#include<string>
#include<map>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
typedef long long ll;
//此题不需要开邻接矩阵,超内存
//想一想,dp[i][j]存的点和距离,side存的也是端点和距离,所以可以省去dp[][]
struct node{
ll x,y;
double d;
}side[300000];
struct Node{
ll x,y;
}dis[751];
ll f[751],cnt;
ll find(ll x){
ll r=x;
while(r!=f[r]){
r=f[r];
}
ll j=x;
while(f[j]!=r){
x=f[j];
f[j]=r;
j=x;
}
return r;
}
int cmp(node a,node b){
return a.d<b.d;
}
int cmp_1(Node a,Node b){
if(a.x==b.x){
return a.y<b.y;
}
return a.x<b.x;
}
int main(){
ll n,m,cnt_s=0;
scanf("%lld",&n);
for(int i=1;i<=n;i++){
f[i]=i;
}
for(int i=1;i<=n;i++){
scanf("%lld %lld",&dis[i].x,&dis[i].y);
}
cnt=0;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
double s=pow(dis[j].y*1.0-dis[i].y*1.0,2)+pow(dis[j].x*1.0-dis[i].x*1.0,2);
side[cnt].x=i;
side[cnt].y=j;
side[cnt++].d=sqrt(s);
}
}
sort(side,side+cnt,cmp);
scanf("%lld",&m);
//将已经建好的加入集合
for(int i=1;i<=m;i++){
ll x,y;
scanf("%lld %lld",&x,&y);
ll tx=find(x);
ll ty=find(y);
if(tx!=ty){
f[tx]=ty;
cnt_s++;
}
}
//如果最小生成树已经生成。。。
if(cnt_s>=n-1){
return 0;
}
Node book[751];
ll cnt_k=0;
for(int i=0;i<cnt;i++){
ll tx=find(side[i].x);
ll ty=find(side[i].y);
if(tx!=ty){
f[tx]=ty;
//存路径
book[cnt_k].x=side[i].x;
book[cnt_k++].y=side[i].y;
cnt_s++;
if(cnt_s>=n-1){
break;
}
}
}
sort(book,book+cnt_k,cmp_1);
for(int k=0;k<cnt_k;k++){
printf("%lld %lld\n",book[k].x,book[k].y);
}
return 0;
}