题目链接:https://vjudge.net/problem/Gym-101063K
题目大意:给你二维平面上n个点,让你选择连接n条线,使其成为一个连通图,注意:任意两点之间连成的线不可经过第三点
分析:n个点,n条边,那就必有一个环。我们可以把这些点按照从小到大(从左下到右上)排序,并依次相连,这样就成为了一个连通图,此时,我们还缺少一条边(使该连通图出现一个环),我们可以比较第一个点分别与其余各点的斜率,找到斜率最小或者斜率最大的,连接即可。
代码:
#include <iostream>
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int n;
struct node
{
int x,y;
int num;
} a[1010];
bool cmp(node u,node v)
{
if(u.x==v.x)
{
return u.y<v.y;
}
return u.x<v.x;
}
int main()
{
cin>>n;
for(int i=1; i<=n; i++)
{
scanf("%d %d",&a[i].x,&a[i].y);
a[i].num=i;
}
sort(a+1,a+n+1,cmp);
double maxx=-INF,minn=INF;
int k1,k2;
for(int i=2; i<=n; i++)
{
double k=(1.0)*(a[1].y-a[i].y)/(a[1].x-a[i].x);
if(k>maxx)
{
maxx=max(k,maxx);
k1=a[i].num;
}
if(k<minn)
{
minn=min(k,minn);
k2=a[i].num;
}
}
if(k1!=a[2].num)
{
cout<<a[1].num<<" "<<k1<<endl;
for(int i=1; i<=n-1; i++)
{
cout<<a[i].num<<" "<<a[i+1].num<<endl;
}
}
else if(k2!=a[2].num)
{
cout<<a[1].num<<" "<<k2<<endl;
for(int i=1; i<=n-1; i++)
{
cout<<a[i].num<<" "<<a[i+1].num<<endl;
}
}
else
{
cout<<-1<<endl;
}
return 0;
}