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]}。node

        同窗們的暑假開始了,我明天卻要回武漢的學校了,在日照待了13天,作了10個題,第二章作完了,看了《揹包九講》,還算滿意吧。暑假來了,是努力的時候了。ios

 

/*
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;
}
相關文章
相關標籤/搜索