这道题不用最短路、不用并查集可行吗?(蒟蒻发问)
查看原帖
这道题不用最短路、不用并查集可行吗?(蒟蒻发问)
1234598
shu10920楼主2025/7/19 14:46

代码在这里,只有60pts(WA on #7 #8 #9 #10)

#include<bits/stdc++.h>
using namespace std;

const int NM = 150;
int X[NM+4],Y[NM+4],T[NM+4];
bool vis[NM+4];
bool F[NM+4][NM+4];
double dis(int x,int y){
	return sqrt((X[x]-X[y])*(X[x]-X[y])+(Y[x]-Y[y])*(Y[x]-Y[y]));
}
int top,n;
double LT[NM+4],D[NM+4],D1[NM+4];//连通块直径、每个点在各自连通块的最长路、备用图 
void dfs(int x,int fa){
	if(vis[x]) return ;
	vis[x] = 1,T[x] = top;
	for(int i = 1;i <= n;i++){
		if(!F[x][i] or i == fa) continue;
		D1[i] = D1[x]+1;
		dfs(i,x);
	}
}
void dfs1(int x,int fa){
	if(vis[x]) return ;
	vis[x] = 1;
	for(int i = 1;i <= n;i++){
		if(!F[x][i] or i == fa) continue;
		D1[i] = D1[x]+1;
		dfs1(i,x);
	}
}
void js(int x){
	top++,dfs(x,0);
	double maxd = 0;
	int id1 = 0,id2 = 0;
	for(int i = 1;i <= n;i++){
		if(D1[i] > maxd) maxd = D1[i],id1 = i;
		D1[i] = 0,vis[i] = 0;
	}
	dfs(id1,0),maxd = 0;
	for(int i = 1;i <= n;i++) if(D1[i] > maxd) maxd = D1[i],id2 = i;
	D1[id1] = 1,maxd = dis(id1,id2);
	for(int i = 1;i <= n;i++) if(D1[i] > 0) LT[i] = maxd,D1[i] = 0;
}
void jsD(int x){
	for(int i = 1;i <= n;i++) if(T[i] == T[x]) D[x] = max(D[x],dis(x,i));
}
int main(){
	ios::sync_with_stdio(false),cin.tie(0);
	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 p;cin>>p;
			if((p-'0')) F[i][j] = 1;
		}
	}
	for(int i = 1;i <= n;i++) if(!T[i]) js(i);
	for(int j = 1;j <= n;j++) if(D[j] == 0) jsD(j);
//	for(int i = 1;i <= n;i++) cout<<T[i]<<' ';
	double ans = 1e18;
	for(int i = 1;i <= n;i++){
		for(int j = 1;j <= n;j++){
			if(T[i] == T[j]) continue;
			double dxp = max({LT[i],LT[j],D[i]+dis(i,j)+D[j]});
//			cout<<i<<' '<<j<<'\n';
//			cout<<LT[i]<<' '<<LT[j]<<' '<<D[i]+dis(i,j)+D[j]<<'\n';
			ans = min(ans,dxp);
		}
	}
	cout<<fixed<<setprecision(6)<<ans<<'\n';
	return 0;
}
2025/7/19 14:46
加载中...