题意是给出一个不连通的图,然后定义了一个直径:联通分量里最短距离最长的两个点之间的距离。
求将一个不连通的图中的两个连通分量连接,生成的这个新分量的直径最小可以有多小,输出这个新直径。
做法是想用Floyd求出任意两点之间的最短距离,然后求出每个点到未生成新图之前的这个点所在分量的最远的一个点的距离。然后枚举联通两个不相连的两个点,这两个点的所在分量的最远距离,加上这两个点之间的距离,就是新生成的牧场的直径。
题目保证一定会有未联通的两个分量:
但是:这道题的第7个测试点我就是死活过不去,然后把这个数据分析了一下发现,这个测试点里的所有点都联通。
在此之前我还专门证明过,一个分量内部的直径一定小于两个分量相连之后新生成的分量的直径。结果题目这种测试数据和题目描述不一致坑的我什么都不想说了。
我就是想问一下人与人之间基本的信任呢
/*
ID: modengd1
PROG: cowtour
LANG: C++
*/
#include <iostream>
#include <stdio.h>
#include <memory.h>
#include <math.h>
#define INF 0xfffffff
using namespace std;
typedef pair<int,int> Coor;
double longestdist[151];
double A[151][151];
Coor coor[151];
bool con[151][151];
int N;
void Floyd()
{//求任意间接联通的两点之间的最短路径,并标记它们之间的间接联通关系for(int k=0;k<N;k++){for(int i=0;i<N;i++){if(A[i][k]!=INF&&k!=i)for(int j=0;j<N;j++){if(A[k][j]!=INF&&k!=j){A[i][j]=min(A[i][j],A[i][k]+A[k][j]);con[i][j]=true;}}}}
}
double dis(Coor A,Coor B)
{return sqrt((A.first-B.first)*(A.first-B.first)+(A.second-B.second)*(A.second-B.second));
}
void slove()
{double ans=INF;//找到每个节点所在分量中离这个节点最远的一个坐标的距离for(int i=0;i<N;i++){for(int j=0;j<N;j++){if(con[i][j]){longestdist[i]=max(longestdist[i],A[i][j]);}}}//枚举任意两个不连通的点并且模拟将这两个点联通之后形成新牧场的直径for(int i=0;i<N-1;i++){for(int j=1+i;j<N;j++){if(!con[i][j]){ans=min(ans,longestdist[i]+longestdist[j]+dis(coor[i],coor[j]));}}}for(int i=0;i<N;i++)//处理假如数据已经全部连通了怎么办(题目强调一定有没连通的两个点,又碰见这种测试数据和题目描述不一样的我也是醉了ans=max(longestdist[i],ans);printf("%.6lf\n",ans);
}
int main()
{freopen("cowtour.in","r",stdin);freopen("cowtour.out","w",stdout);scanf("%d",&N);int a,b;char ch;for(int i=0;i<N;i++){scanf("%d%d",&a,&b);coor[i].first=a;coor[i].second=b;}getchar();for(int i=0;i<N;i++){for(int j=0;j<N;j++){scanf("%c",&ch);if(ch=='0')//判断是否直接联通并且初始化用来Floyd的A数组{con[i][j]=false;A[i][j]=INF;}else{con[i][j]=true;A[i][j]=dis(coor[i],coor[j]);}}getchar();con[i][i]=true;//自己到自己一定是联通的且距离为0A[i][i]=0;}Floyd();slove();return 0;
}