USACO2.4 Cow Tours(cowtour)

        第二章我最后做的这个题,一个最短路的题,输入邻接矩阵,先dfs计算牧场数量,然后对每一个牧场用floyd算法求牧区相互之间的最短路,并将牧区k中到所有牧区到牧区i的最大距离保存为da[k][i],以便后面的距离比较,然后任意选择两个牧场k、kk,每个牧场选一个牧区i、j,cal(i,j)是两牧区连线距离,da[k][i]、da[kk][j]是牧场k/kk的牧区到牧区i/j的最大距离,temp=min{da[k][i]+cal(i,j),da[kk][j]},于是ans=max{temp,da[k][i]}。

        同学们的暑假开始了,我明天却要回武汉的学校了,在日照待了13天,做了10个题,第二章做完了,看了《背包九讲》,还算满意吧。暑假来了,是努力的时候了。

 

/*
ID:jzzlee1
PROB:cowtour
LANG:C++
*/
//#include <iostream>
#include<fstream>
#include<string>
#include<cmath>
#include<cstdio>
#include<iomanip>
using namespace std;
ifstream cin("cowtour.in");
ofstream cout("cowtour.out");
struct node
{
	double x;
	double y;
	int number;
}a[150];
int name[150][150],len[150],vis[150],n;
double d[150][150],da[150][150],ans=20000000;
char str[150][150];
void dfs(int k,int cnt)
{
	int i;
	vis[k]=1;
	a[k].number=cnt;
	for(i=0;i!=n;i++)
	{
		if(vis[i]==0&&str[k][i]=='1')
		dfs(i,cnt);
	}
}
void cal_d()
{
	int i,j;
	for(i=0;i!=n;i++)
		for(j=i;j!=n;j++)
		{
			if(str[i][j]=='1')
			{
				d[i][j]=d[j][i]=sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
			}
			else if(i!=j)
				d[i][j]=d[j][i]=20000000;
		}
}
double cal(int i,int j)
{
	return sqrt((a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y));
}
void floyd(int num,int nam[])
{
	int i,j,k;
	for(k=0;k<num;k++)
		for(i=0;i<num;i++)
			for(j=0;j<num;j++)
				if(d[nam[i]][nam[k]]+d[nam[k]][nam[j]]<d[nam[i]][nam[j]])
					d[nam[i]][nam[j]]=d[nam[i]][nam[k]]+d[nam[k]][nam[j]];
}
void maxlen(int num,int nam[],double dd[])
{
	int i,j;
	for(i=0;i!=num;i++)
		for(j=0;j!=num;j++)
			if(d[nam[i]][nam[j]]>dd[i])
				dd[i]=d[nam[i]][nam[j]];
}
int main()
{
	int k,i,j;
	cin>>n;
	for(i=0;i!=n;++i)
		cin>>a[i].x>>a[i].y;
	getchar();
	for(i=0;i!=n;i++)
	{
		for(j=0;j!=n;j++)
			cin>>str[i][j];
		getchar();
	}
	int areanum=0;
	for(i=0;i!=n;i++)
		if(vis[i]==0)
			dfs(i,areanum++);
	for(k=0;k!=areanum;k++)
		for(i=0;i!=n;i++)
			if(a[i].number==k)
				name[k][len[k]++]=i;
	cal_d();
	for(k=0;k!=areanum;k++)
		floyd(len[k],name[k]);
	for(k=0;k!=areanum;k++)
		maxlen(len[k],name[k],da[k]);
	for(k=0;k!=areanum;k++)
		for(int kk=0;kk!=areanum;kk++)
			for(i=0;kk!=k&&i!=len[k];i++)
				for(j=0;j!=len[kk];j++)
					if(ans>da[k][i]+cal(name[k][i],name[kk][j])+da[kk][j])
						ans=da[k][i]+cal(name[k][i],name[kk][j])+da[kk][j];
		for(k=0;k!=n;k++)
			for(i=0;i!=n;i++)
				if(ans<da[k][i])
					ans=da[k][i];
	cout<<setiosflags(ios::fixed)<<setiosflags(ios::right)<<setprecision(6)<<ans<<endl;;
	return 0;
}

你可能感兴趣的:(USACO)