看题目说只有两个牧场,就想当然的以为每个牧场内两两联通,结果就暴力分成两个set,然后对每个set求floyd求最短路,结果发现数据中有全部不联通的这种数据,无奈参考标程使用并查集,代码忘记保存了,就不发了。。。。‘
code:这是标程
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <memory.h>
const int maxn = 175;
const double INF = 1E15;
int N, x[maxn], y[maxn], parent[maxn];
double vert[maxn], dist[maxn][maxn];
double dis( int x1, int y1, int x2, int y2 )
{
return ( sqrt( 1.0*(x1-x2)*(x1-x2)+1.0*(y1-y2)*(y1-y2) ) );
}// distance
int FindSet( int k )
{
while ( k!=parent[ k ] )
k = parent[ k ];
return k;
}// FindSet
void Merge( int xx, int yy )
{
int r1 = FindSet( xx );
int r2 = FindSet( yy );
if ( r1==r2 )
return ;
if ( r1<r2 )
parent[ r2 ] = r1;
else
parent[ r1 ] = r2;
}// Merge
void ReadData()
{
char c;
int i, j;
scanf("%d", &N);
for ( i=1; i<=N; ++i )
{
vert[i] = -1, parent[i] = i;
scanf("%d %d", &x[i], &y[i]);
}// coordinare
for ( i=1; i<=N; ++i )
{
getchar();
for ( j=1; j<=N; ++j )
{
scanf("%c", &c);
if ( i==j ) dist[i][j] = 0;
else if ( c=='0' ) dist[i][j] = INF;
else if ( c=='1' )
{
Merge( i, j );
dist[i][j] = dis( x[i], y[i], x[j], y[j] );
}
}
}// creat the graph
}// ReadData
void Floyd()
{
for ( int k=1; k<=N; ++k )
{
for ( int i=1; i<=N; ++i )
{
for ( int j=1; j<=N; ++j )
{
if ( k==i || k==j ) continue;
if ( dist[i][k]+dist[k][j]<dist[i][j] )
dist[i][j] = dist[i][k]+dist[k][j];
}
}
}
}// Floyd
void Solve()
{
int i, j;
double dd, lowcost;
for ( i=1; i<=N; ++i )
{
for ( j=1; j<=N; ++j )
{
if ( dist[i][j]!=INF && vert[i]<dist[j][i] )
vert[i] = dist[j][i];
}
}// Find the longest path of the shortest path
lowcost = INF;
for ( i=1; i<=N; ++i )
{
for ( j=i+1; j<=N; ++j )
{
if ( dist[i][j]==INF && parent[i]!=parent[j] )
{
dd = dis( x[i], y[i], x[j], y[j] );
if ( vert[i]+dd+vert[j]<lowcost )
lowcost = vert[i]+dd+vert[j];
}
}
}// Find the shortest path
for ( i=1; i<=N; ++i )
{
if ( vert[i]>lowcost )
lowcost = vert[i];
}
printf("%.6lf\n", lowcost);
}// Solve
int main()
{
freopen("cowtour.in", "r", stdin);
freopen("cowtour.out", "w", stdout);
ReadData();
Floyd();
Solve();
return 0;
}