我是靠谱客的博主 还单身雪糕,最近开发中收集的这篇文章主要介绍【换行符的问题】牛的旅行(洛谷1522),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

传送门
先读懂题意哈,题意就是,我们连接两个牧场得到一个新牧场,然后在所有新牧场中输出直径最小的牧场的直径。
然后,看着n最大150,感觉就像枚举。
然后我们按枚举算一下复杂度,应该是三次方,刚好。
所以我们的思路是,用邻接链表存图。然后用Floyd处理出最短路。
接下来我们需要处理出未连接时每个牧场的直径,以及每个牧场内每一个点到同一牧场其他点的距离中最大的距离。
接下来只要枚举点对就行了。
每次枚举出一个点对,判断是否属于同一牧场,如果不属于,就把他们连在一起,计算该新牧场的直径,然后和答案比对即可。
至于新牧场的直径如何求,我们想一下,对于一个由A和B(设接点为a和b)两个旧牧场组成的新牧场,它的直径只有三种情况:

  • A的直径
  • B的直径
  • a到A内部其他点的距离最大值,加上b到B内部其他点的距离最大值,再加上新连的边的长度(也就是a到b的长度)

所以只要取这三者的最大值然后和答案比对即可。
当然,保存牧场可以用并查集,也可以不用并查集,直接用两点是否联通来判断(Floyd处理后)。
顺带一提,对于01表的读入方式,最好采用限定位数的整数读入。如下:

scanf("%1d",&d);

在%和d之间加上一个数字1即可,表示只读一位数。
当然,你也可以用字符读入。
但是你要注意,换行符的存在。
尤其是Linux和Windows环境下的换行符是不一样的。
Windows下只要读一个字符即可把换行符读完,但Linux下要读两个字符才可以。
所以最后代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=200;
struct point{
	int xx,yy;
}pt[maxn];
int n;
int vv[maxn];
double mapp[maxn][maxn];
double d[maxn];
double area[maxn];
int p[maxn];
double calc(int a,int b){
	return sqrt(pow(pt[a].xx-pt[b].xx,2)+pow(pt[a].yy-pt[b].yy,2));
}
int find(int cur){
	return cur==p[cur]?cur:p[cur]=find(p[cur]);
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d%d",&pt[i].xx,&pt[i].yy);
	}
	memset(mapp,0x42,sizeof(mapp));
	for(int i=1;i<=n;i++){
		p[i]=i;
	}
	for(int i=1;i<=n;i++){
		mapp[i][i]=0;int vis;
		for(int j=1;j<=n;j++){
			scanf("%1d",&vis);
			if(vis==1&&i<j){
				mapp[i][j]=mapp[j][i]=calc(i,j);
				p[find(j)]=find(i);
			}
		}
	}
	memset(vv,0,sizeof(vv));
	for(int i=1;i<=n;i++){
		vv[find(i)]=1;
	}
	memset(d,0xc2,sizeof(d));
	memset(area,0xc2,sizeof(area));
	for(int k=1;k<=n;k++){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				mapp[i][j]=min(mapp[i][j],mapp[i][k]+mapp[k][j]);
				
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(mapp[i][j]<mapp[0][0]){
				d[i]=max(d[i],mapp[i][j]);
			}
		}
	}
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++){
			int x=find(i),y=find(j);
			if(x==y){
				area[x]=max(area[x],mapp[i][j]);
			}
		}
	}
	double ans=1000000000000.0;
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++){		
			int u=find(i),v=find(j);
			if(u!=v){
				ans=min(ans,max(calc(i,j)+d[i]+d[j],max(area[u],area[v])));
			}
		}
	}
	printf("%.6f",ans);
	return 0;
} 

最后

以上就是还单身雪糕为你收集整理的【换行符的问题】牛的旅行(洛谷1522)的全部内容,希望文章能够帮你解决【换行符的问题】牛的旅行(洛谷1522)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部