P1522 牛的旅行 Cow Tours·最短路
程序员文章站
2022-03-21 07:50:36
...
题解
大致题意:给两个连通图添加一条路,使得最远的两个点之间的最短路的值最小
这里的最小的最短路有可能是原本同一个连通图里的最远最短路,也有可能是添加了新边后形成的最远最短路
由于最远的路径由任意两个点组成起点和终点,所以首选Floyd
大致步骤:
1.先求出同一连通图里各个点之间的最短路 - Floyd,如果起终点不是同一个图里的,dis[i][j]显示为最大值
2.求出对于每个点来说,最远的点离它的最短路距离
3.找到连通图里最远的那条最短路,标记为s1
4.之后给不连通的两点之间添一条路,其最远距离应该为 离i最远的距离+i,j之间的距离+离j最远的距离,当然我们添加的边形成的新的最短路,一定是所有添加可能里的最短的那条,标记为s2
5.判断s1和s2里的最大值
#include <bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=1e3+10;
char s[N];
double ans=0.0;
int n;
struct node{
int x,y;
void input(){
cin>>x>>y;
}
double distance(const node& b)const{
return sqrt((x-b.x)*(x-b.x)+(y-b.y)*(y-b.y));
}
}a[N];
double dis[N][N],far[N];
int main()
{
cin>>n;
for (int i = 1; i <= n; i++) a[i].input();
for (int i = 1; i <= n; i++) {
cin>>s;
for (int j = 1; j <= n; j++) {
if(s[j-1]=='1') //s[]='0'时判断是为真!
dis[i][j]=a[i].distance(a[j]);
else if(i!=j)dis[i][j]=INF;//顺便初始化
}
}
//先求出任意两点之间的最短路
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if(dis[i][j]>dis[i][k]+dis[k][j])
dis[i][j]=dis[i][k]+dis[k][j];
}
}
}
//然后找到相对于每个点来说 最远的那个点和它的距离
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if(dis[i][j]!=INF) far[i]=max(dis[i][j],far[i]);
ans=max(ans,far[i]);//找到最远的那个就是联通图内部的直径
}
}
//连接两个连通图
double ans2=INF;//不会影响答案 因为题目说了必定有两个连通图
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if(dis[i][j]==INF)
ans2=min(ans2,far[i]+a[i].distance(a[j])+far[j]);
}
}
ans=max(ans,ans2);//找到两者间最大的那个
printf("%.6f\n",ans);
return 0;
}
上一篇: P1101 单词方阵_题解