2020 GDUT Rating Contest Ⅱ A. Fence Planning

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);
}
发布了24 篇原创文章 · 获赞 1 · 访问量 663

猜你喜欢

转载自blog.csdn.net/palax0/article/details/104819106