90分 WA#7 求调
查看原帖
90分 WA#7 求调
582368
chong_yu楼主2023/10/6 19:14

如题,答案是39796.392691,我的输出是22693.893986

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=160;
int x[N],y[N],g[N][N];
int f[N];
double dis[N][N],maxv[N],d[N];
double MAX=2e9;
vector<int> p[N],v;
int find(int x){
	if(f[x]==x){
		return x;
	}else{
		return find(f[x]);
	}
}
double distance(int x1,int y1,int x2,int y2){
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
signed main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>x[i]>>y[i];
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			char c;
			cin>>c;
//			cin>>g[i][j];
			if(c=='1'){
				g[i][j]=1;
				dis[i][j]=distance(x[i],y[i],x[j],y[j]);
			}else if(i==j){
				g[i][j]=1;
				dis[i][j]=0;
			}else{
				g[i][j]=0;
				dis[i][j]=MAX;
			}
		}
	}
	
	//第一步:处理出连通块 
	for(int i=1;i<=n;i++){
		f[i]=i;
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(g[i][j]==1){
				f[j]=find(i);
			}
		}
	}
	for(int i=1;i<=n;i++){
		if(find(i)==i){
			v.push_back(i);
		}
		p[find(i)].push_back(i);
	}
	for(auto u:v){
		for(auto k:p[u]){
			for(auto i:p[u]){
				for(auto j:p[u]){
					if(dis[i][j]>dis[i][k]+dis[k][j]){
						dis[i][j]=dis[i][k]+dis[k][j];
					}	
				}
			}
		}
		for(auto i:p[u]){
			for(auto j:p[u]){
				maxv[u]=max(maxv[u],dis[i][j]);
			}
		}
	}
	
	//处理出从每个点出发的最远距离
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(dis[i][j]<MAX){
				d[i]=max(d[i],dis[i][j]);
			}
		}
	} 
	
	//找结果
	double res=MAX;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(i!=j&&find(i)!=find(j)){
				res=min(res,max(max(maxv[find(i)],maxv[find(j)]),d[i]+d[j]+distance(x[i],y[i],x[j],y[j])));
			}
		}
	}
	printf("%.6lf",res);
	return 0;
}
2023/10/6 19:14
加载中...