1. 程式人生 > >洛谷1522 牛的旅行 floyed

洛谷1522 牛的旅行 floyed

 點少,標準的floyed。先用floyed更新出任意兩點之間的最短距離。用並查集標記在同一牧場的的點。最後列舉兩個不同牧場的點之間的距離len3,以及各自和自己牧場中最遠的距離len1,len2.我們求的結果就是最小的(len1+len2+len3)。

然後第七個點一直過不去。後來發現,少考慮了一種情況,就是可能兩個原牧場中的某一個直徑可能大於len1+len2+len3。。。。。。。。。。找了三個小時

#include <bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define res register int 
const int maxn=155;
char G[maxn][maxn];
double dis[maxn][maxn];
int fa[maxn];
int N;
struct Node{
	double x,y;
}node[maxn];
double cal(int a,int b){
	return sqrt(abs(node[a].x-node[b].x)*abs(node[a].x-node[b].x)+abs(node[a].y-node[b].y)*abs(node[a].y-node[b].y));
}
int find(int x){
	if(x==fa[x]) return x;
	else return fa[x]=find(fa[x]);
}
void unit(int x,int y){
	x=find(x);
	y=find(y);
	if(x!=y) fa[x]=y;
	return;
}
void init()
{
	cin>>N;
	for(res i=1;i<=N;i++){
		fa[i]=i;
		scanf("%lf%lf",&node[i].x,&node[i].y);
	}
	for(res i=1;i<=N;i++){
		char temp[maxn];
		scanf("%s",temp);
		sprintf(G[i],"#%s",temp);
	}
	for(res i=1;i<=N;i++)
		for(res j=1;j<=N;j++)
			dis[i][j]=inf;
	for(res i=1;i<=N;i++){
		for(res j=1;j<i;j++){
			if('1'==G[i][j]){
				unit(j,i);
				dis[i][j]=dis[j][i]=cal(i,j);
			}
		} 
	}
	for(res i=1;i<=N;i++)
		dis[i][i]=0;
}

void floyed()
{
	for(res k=1;k<=N;k++)
		for(res i=1;i<=N;i++)
			for(res j=1;j<=N;j++)
				dis[i][j]=dis[j][i]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
int main()
{
	init();
	floyed();
	double len=inf;
	for(res i=1;i<=N;i++)
		for(res j=i+1;j<=N;j++){
			double len1=-inf,len2=-inf,len3=-inf;//len1表示的是第一個牧場到該點的距離 len2是第二個  len3表示的是兩點之間的距離 
			if(find(i)!=find(j)){
				len3=cal(i,j);
				//開始找第i個點所在牧場裡面所有的點到i點最大的距離 
				for(res k=1;k<=N;k++)
					if(find(k)==find(i)) len1=max(len1,dis[i][k]);
				//開始找第j個點所在牧場裡面所有的點到j點最大的距離 
				for(res k=1;k<=N;k++)
					if(find(k)==find(j)) len2=max(len2,dis[j][k]);
				len=min(len,len1+len2+len3);
			}	
		}
	printf("%.6lf",len);
	return 0;
}