USACO SECTION 2.4 Cow Tours

本文深入探讨了大数据开发领域的关键技术,包括Hadoop、Spark、Flink等,并阐述了它们在实际应用中的重要性及优势。
Cow Tours

Farmer John has a number of pastures on his farm. Cow paths connect some pastures with certain other pastures, forming a field. But, at the present time, you can find at least two pastures that cannot be connected by any sequence of cow paths, thus partitioning Farmer John's farm into multiple fields.

Farmer John would like add a single a cow path between one pair of pastures using the constraints below.

A field's `diameter' is defined to be the largest distance of all the shortest walks between any pair of pastures in the field. Consider the field below with five pastures, located at the points shown, and cow paths marked by lines:

                15,15   20,15
                  D       E
                  *-------*
                  |     _/|
                  |   _/  |
                  | _/    |
                  |/      |
         *--------*-------*
         A        B       C
         10,10   15,10   20,10

The `diameter' of this field is approximately 12.07106, since the longest of the set of shortest paths between pairs of pastures is the path from A to E (which includes the point set {A,B,E}). No other pair of pastures in this field is farther apart when connected by an optimal sequence of cow paths.

Suppose another field on the same plane is connected by cow paths as follows:

                         *F 30,15
                         / 
                       _/  
                     _/    
                    /      
                   *------ 
                   G      H
                   25,10   30,10

In the scenario of just two fields on his farm, Farmer John would add a cow path between a point in each of these two fields (namely point sets {A,B,C,D,E} and {F,G,H}) so that the joined set of pastures {A,B,C,D,E,F,G,H} has the smallest possible diameter.

Note that cow paths do not connect just because they cross each other; they only connect at listed points.

The input contains the pastures, their locations, and a symmetric "adjacency" matrix that tells whether pastures are connected by cow paths. Pastures are not considered to be connected to themselves. Here's one annotated adjacency list for the pasture {A,B,C,D,E,F,G,H} as shown above:

                A B C D E F G H
              A 0 1 0 0 0 0 0 0
              B 1 0 1 1 1 0 0 0
              C 0 1 0 0 1 0 0 0
              D 0 1 0 0 1 0 0 0
              E 0 1 1 1 0 0 0 0
              F 0 0 0 0 0 0 1 0
              G 0 0 0 0 0 1 0 1
              H 0 0 0 0 0 0 1 0

Other equivalent adjacency lists might permute the rows and columns by using some order other than alphabetical to show the point connections. The input data contains no names for the points.

The input will contain at least two pastures that are not connected by any sequence of cow paths.

Find a way to connect exactly two pastures in the input with a cow path so that the new combined field has the smallest possible diameter of any possible pair of connected pastures. Output that smallest possible diameter.

PROGRAM NAME: cowtour

INPUT FORMAT

Line 1:An integer, N (1 <= N <= 150), the number of pastures
Line 2-N+1:Two integers, X and Y (0 <= X ,Y<= 100000), that denote that X,Y grid location of the pastures; all input pastures are unique.
Line N+2-2*N+1:lines, each containing N digits (0 or 1) that represent the adjacency matrix as described above, where the rows' and columns' indices are in order of the points just listed.

SAMPLE INPUT (file cowtour.in)

8
10 10
15 10
20 10
15 15
20 15
30 15
25 10
30 10
01000000
10111000
01001000
01001000
01110000
00000010
00000101
00000010

OUTPUT FORMAT

The output consists of a single line with the diameter of the newly joined pastures. Print the answer to exactly six decimal places. Do not perform any special rounding on your output.

SAMPLE OUTPUT (file cowtour.out)

22.071068

 

/*
ID: conicoc1
LANG: C
TASK: cowtour
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>

#define INIFINITY 15000000

typedef struct Pastures Pastures;
struct Pastures
{
	int x;
	int y;
};

Pastures Pas[150];
int PasN;
int Matrix[150][150];
double Dist[150][150];
double FieldSize=0,MinFieldSize=INIFINITY,temp;

double Max(double a,double b)
{
	return a>b?a:b;	
}

double Min(double a,double b)
{
	return a>b?b:a;
}

double Distance(int i,int j)
{
	return sqrt((Pas[i].x-Pas[j].x)*(Pas[i].x-Pas[j].x)+(Pas[i].y-Pas[j].y)*(Pas[i].y-Pas[j].y));
}
void InitialDist()
{
	int i,j;
	for(i=0;i<PasN;i++)
		for(j=0;j<PasN;j++)
			Dist[i][j]=INIFINITY;
}

double FindMaxDist(int i)
{
	int j;
	double MaxDist=0;
	for(j=0;j<PasN;j++){
		if(Dist[i][j]!=INIFINITY&&MaxDist<Dist[i][j])
			MaxDist=Dist[i][j];
	}
	return MaxDist;
} 

int main()
{
	FILE *fin,*fout;
	int i,j;
	int k,t,s;
	char c;
	fin=fopen("cowtour.in","r");
	fout=fopen("cowtour.out","w");
	
	fscanf(fin,"%d",&PasN);
	InitialDist();
	
	for(i=0;i<PasN;i++)
		fscanf(fin,"%d %d",&Pas[i].x,&Pas[i].y);
	for(i=0;i<PasN;i++){
		for(j=0;j<PasN;j++){
			while((c=getc(fin))!='0'&&c!='1');
				Matrix[i][j]=c-'0';
			if(Matrix[i][j]==1)
			{
				Dist[i][j]=Distance(i,j);
				printf("%.1lf ",Dist[i][j]);
			}
			if(i==j)
				Dist[i][j]=0;
		}
	}
	//计算所有点对路径 
	for(k=0;k<PasN;k++){
		for(i=0;i<PasN;i++){
			for(j=0;j<PasN;j++){
				if(Dist[i][j]>Dist[i][k]+Dist[k][j])
					Dist[i][j]=Dist[i][k]+Dist[k][j];
			}
		}
	}
	
	//计算最大牧场大小 
	for(i=0;i<PasN;i++){
		for(j=0;j<PasN;j++){
			if(Dist[i][j]!=INIFINITY) 
			FieldSize=Max(FieldSize,Dist[i][j]);
		}
	}
		 
	for(i=0;i<PasN;i++){
		for(j=0;j<PasN;j++){
			if(Dist[i][j]==INIFINITY){
				temp=Distance(i,j)+FindMaxDist(i)+FindMaxDist(j);
				MinFieldSize=Min(Max(temp,FieldSize),MinFieldSize);	
			}
		}
	}
	
	fprintf(fout,"%.6lf\n",MinFieldSize);
	return 0;
}


最慢0.05秒AC

做完才发现,其实USACO这道题的测试数据真的不够强力啊

因为一开始的牧场我没有看到是至少2个,我以为是等于2个。

那我们来分析一下为什么能AC

 

首先求出了直径最大的牧场

因为添加一条线至多连接两个牧场A,B

所以添加一条线后,直径最大的牧场可能有3种情况:

1.未添加线时直径最大的牧场,FieldSize

2.A和B直径中大的那个

3.经过连线的最大直径

显然当我们选择一组测试数据,当这个测试数据中未添加连线时的最大的牧场既不是A也不是B,且第二种情况大于第三种情况的时候,就会发生错误

所以我们应该统计出每个牧场的Size,比较最大值。

 

想到这里,我发现上面的说法是错误的= =!!!!!!

因为第一种情况深深的包含了第二种啊!!!尼玛我是误打误撞AC了啊。。晕= =

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值