A. Fence Planning
题目描述
给出 n 头牛的二维坐标和 m对 牛之间的关系,而有关系的牛算作同一组。这个关系可以传递,如给出关系1-2、2-3,则1、2、3为一组。现在想用一个矩形围栏将其中一个组围住,求围栏周长的最小值。
题目分析
先用并查集处理牛的关系,得出各牛属于哪一组,再遍历每头牛的横纵坐标,找出每组横坐标与纵坐标的最大最小值,即可算出每组最少需要的围栏周长,最后比较哪组周长最小即可。
代码
#include <bits/stdc++.h>
using namespace std;
struct point{
int x;
int y;
};
struct maxmin{//用于存每个组的max/min x/y
int root;
int max_x;
int max_y;
int min_x;
int min_y;
};
point cow[100001];
maxmin moo[100001];
int pre[100001];
int p=0;
int union_search(int x){
int son=x,temp;
while(pre[x]!=x){
x=pre[x];
}
while(son!=x){
temp=pre[son];
pre[son]=x;
son=temp;
}
return x;
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
pre[i]=i;
scanf("%d%d",&cow[i].x,&cow[i].y);
}
int a,b,root_a,root_b;
for(int i=0;i<m;i++){
scanf("%d%d",&a,&b);
root_a=union_search(a),root_b=union_search(b);
if(root_a!=root_b){
pre[root_b]=root_a;
}
}
int root;
for(int i=1;i<=n;i++){
root=union_search(i);
if(moo[root].root==0){
moo[root].root=root;
moo[root].max_x=cow[i].x;
moo[root].max_y=cow[i].y;
moo[root].min_x=cow[i].x;
moo[root].min_y=cow[i].y;
}
else{
moo[root].max_x=max(moo[root].max_x,cow[i].x);
moo[root].max_y=max(moo[root].max_y,cow[i].y);
moo[root].min_x=min(moo[root].min_x,cow[i].x);
moo[root].min_y=min(moo[root].min_y,cow[i].y);
}
}
int ans=0x7FFFFFFF;//如果不是最大会wa
for(int i=1;i<=n;i++){
if(moo[i].root!=0){
int temp=2*(moo[i].max_x-moo[i].min_x+moo[i].max_y-moo[i].min_y);
//printf("max_x=%d,max_y=%d,min_x=%d,min_y=%d\n",moo[i].max_x,moo[i].max_y,moo[i].min_x,moo[i].min_y);
//printf("ans=%d,temp=%d,i=%d\n",ans,temp,i);
ans=min(ans,temp);
}
}
printf("%d\n",ans);
}