60pts #WA6本地测试通过但是提交不过
查看原帖
60pts #WA6本地测试通过但是提交不过
671223
OAIM楼主2024/3/1 09:14
//牛的旅行Cow Tours

//至少两个牧区不连通
//新增一条路径使新牧场的直径尽可能小
//求新牧场直径的最小值
//无向图 
//数字保留小数点后6位
//一个牧区的直径是牧场中最大的最短路 

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

const int N = 150;
const double INF = 1e7;

int n;//牧区数(点数)
double x[N],y[N];//牧区坐标(点的坐标) 
int m[N][N];//邻接矩阵
double g[N][N];//两点之间的权值 
int p[N];//并查集祖先节点
double sz[N];//所在牧场的直径 
double dist[N][N];//两点之间的最短距离 
double d[N];//从各点到其他点的最长最短路 
double ans = INF;

//初始化并查集
void init(){
	for(int i = 1;i <= n;i++){
		p[i] = i;
	}
} 

//查找祖先节点
int find(int x){
	if(p[x] != x){
		p[x] = find(p[x]);
	}
	
	return p[x];
} 

//Floyd算法
void floyd(){
	for(int k = 1;k <= n;k++){
		for(int i = 1;i <= n;i++){
			for(int j = 1;j <= n;j++){
				dist[i][j] = min(dist[i][j],dist[i][k] + dist[k][j]);
			}
		}
	}
} 

int main(){
	//输入
	//scanf("%d",&n);
	cin >> n; 
	//初始化邻接矩阵
	//memset(g,0x3f,sizeof(g)); 
	for(int i = 1;i <= n;i++){
		//scanf("%lf %lf",&x[i],&y[i]);
		cin >> x[i] >> y[i];
	} 
	//初始化并查集
	init(); 
	//初始化距离
	//memset(dist,0x3f,sizeof(dist));
	for(int i = 1;i <= n;i++){
		for(int j = 1;j <= n;j++){
			dist[i][j] = INF;
		}
	}
	char op;
	for(int i = 1;i <= n;i++){
		//char s[N];
		//scanf("%s",s);
		//string s;
		//cin >> s;
		for(int j = 1;j <= n;j++){
			//scanf("%c",&m[i][j]);
			//cin >> m[i][j];
			//m[i][j] = s[j - 1];
			//scanf("%1d",&op);
			/*do{
				op = getchar();
			}while(op != '0' && op != '1');*/
			//cin >> op;
			/*do{
				scanf("%c",&op);
			}while(op != '0' && op != '1');*/
			scanf("%1d",&m[i][j]);
			if(i == j){
				dist[i][j] = 0;
			}else if(m[i][j] == 1){
				//两点直接相连 
				dist[i][j] = sqrt((y[j] - y[i]) * (y[j] - y[i]) + (x[j] - x[i]) * (x[j] - x[i]));
				//合并节点到同一集合中
				if(find(i) != find(j)){
					p[find(i)] = find(j);
				}
			} 
		}
	}
	
	/*for(int i = 1;i <= n;i++){
		for(int j = 1;j <= n;j++){
			printf("%lf ",dist[i][j]);
		}
		printf("\n");
	}*/
	
	//求任意两点之间的距离
	floyd(); 
	
	//求从各点到所在牧区中其他点的最长最短路 
	for(int i = 1;i <= n;i++){
		for(int j = 1;j <= n;j++){
			if(dist[i][j] != INF){
				d[i] = max(dist[i][j],d[i]);
				sz[find(i)] = max(sz[find(i)],d[i]);
			}
		}
	}
	
	 
	
	//枚举
	for(int i = 1;i <= n;i++){
		for(int j = 1;j <= n;j++){
			if(find(i) != find(j)){
				double ij = sqrt((y[j] - y[i]) * (y[j] - y[i]) + (x[j] - x[i]) * (x[j] - x[i]));
				//不在一个集合里
				ans = min(ans,max(d[i] + d[j] + ij,max(sz[find(i)],sz[find(j)])));
			}
		}
	} 
	
	//输出
	printf("%.6lf\n",ans); 
	
	return 0;
} 
2024/3/1 09:14
加载中...