洛谷P1522牛的旅行——多源最短路

题目:https://www.luogu.org/problemnew/show/P1522

或者http://111.231.101.32/problem.php?id=1001(自建OJ,欢迎光临)

分析:

step1、用floyed求出任两点最短路径;

step2、求出同一联通块中任一点可以到达的最远距离,记作maxdis[i],并求出maxdis[i]的最大值maxx1;

step3、枚举不联通的两个点,求出maxdis[i]+maxdis[j]+(i,j间的距离)中的最小值maxx2;

step4、输出答案max(maxx1,maxx2)。

为什么输出max(maxx1,maxx2),下图可以非常直观地说明,答案显而易见是20.000000:

AC代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int a[155][2];
double dis[155][155],maxdis[155];

double dist(int i,int j){
	return sqrt( (double)( (a[i][0]-a[j][0])*(a[i][0]-a[j][0]) ) 
				+ (double)( (a[i][1]-a[j][1])*(a[i][1]-a[j][1])) );
}
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i][0]>>a[i][1];
		
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if(i!=j)dis[i][j]=1e15;
	char x;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++){
			cin>>x;
			if(x=='1'){
				dis[i][j]=dist(i,j);
		}	
	}
	
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				if(i!=k && j!=k && i!=j 
				&& dis[i][j]>dis[i][k]+dis[k][j])
					dis[i][j]=dis[i][k]+dis[k][j];
					
	double maxx1=0;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(i==j)continue;
			if(dis[i][j]<1e15 
			&& maxdis[i]<dis[i][j])
				maxdis[i]=dis[i][j];
		}
		if(maxx1<maxdis[i])maxx1=maxdis[i];	
	}
		
	double maxx2=1e15;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++){
			if(i==j)continue;
			if(dis[i][j]==1e15 
			&&maxx2>maxdis[i]+maxdis[j]+dist(i,j) )
				maxx2=maxdis[i]+maxdis[j]+dist(i,j);
		}
	printf("%.6f\n",maxx1>maxx2?maxx1:maxx2);
	return 0;		
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值