Floyd最短路 - 牛的旅行 Cow Tours

传送门


Analysis

比较基础了
先用Floyd求出任意相连的两点的最短路,然后预处理出每一个点往外最多能延伸的长度mx[i]
最后暴力N2枚举加边
但需要注意一点,有可能你加入的边是你能加的最小直径了,但这个“直径”并不是牧场中最远两点的距离
所以你还要将加边后求出来的直径长度与不加边时的直径长度取max

注意一点,在求mx[i]的时候不能想着方便就一边做Floyd一边在中途取max
因为Floyd相当于也是在进行松弛操作,你的mx存的就是最短路中的最大值了


Code

#include
#define in read()
#define inf (1ll<<31)
using namespace std;
inline int read(){
	char ch;int f=1,res=0;
	while((ch=getchar())<'0'||ch>'9') if(ch=='-') f=-1;
	while(ch>='0'&&ch<='9'){
		res=(res<<3)+(res<<1)+ch-'0';
		ch=getchar();
	}
	return f==1?res:-res;
}
int n;
struct node{
	double x,y;
}p[205];
double mx[205];
double g[205][205];
double calc(int a,int b){
	return sqrt((p[a].x-p[b].x)*(p[a].x-p[b].x)+(p[a].y-p[b].y)*(p[a].y-p[b].y));
}
int main(){
	scanf("%d",&n);
	int i,j,k;
	for(i=0;i<n;++i)
		scanf("%lf%lf",&p[i].x,&p[i].y);
	char st[205];
	for(i=0;i<n;++i)
	{
		scanf("%s",st);
		for(j=0;j<n;++j)
		{
			int c=st[j]-'0';
			if(c==1)	g[i][j]=calc(i,j);
			else g[i][j]=inf;
		}
	}	
	for(i=0;i<n;++i) g[i][i]=0;
	for(k=0;k<n;++k)
		for(i=0;i<n;++i)
			for(j=0;j<n;++j)
				if(g[i][k]+g[k][j]<g[i][j]){//怎么可以在求最短路的时候求max呢??那不就是保留的第一次的最大值了?? 
					g[i][j]=g[i][k]+g[k][j];
				} 
	for(i=0;i<n;++i)
		for(j=0;j<n;++j)
			if(g[i][j]<inf&&mx[i]<g[i][j]) mx[i]=g[i][j]; 
	double ans1=0.0,ans2=1e20;
	for(i=0;i<n;++i) ans1=max(mx[i],ans1);
	for(i=0;i<n;++i)
		for(j=0;j<n;++j)
			if(g[i][j]==inf)
				ans2=min(ans2,mx[i]+mx[j]+calc(i,j));
	printf("%.6lf",max(ans2,ans1));
	return 0;
} 

你可能感兴趣的:(FLOYD)