您的位置:首页 > 其它

usaco Cow Tours

2015-09-04 20:04 351 查看
多源最短路

弗洛伊德算法+并查集

很适合用来训练图论的思维/*
ID:zhdxzwj1
LANG:C++
PROG:cowtour
*/
#include <bits/stdc++.h>
double ma[152][152];
char flag[152][152];
char fei;
double d[152];
double dd[152]={0};
struct vertex
{
int x,y;
}v[152];
int bing[152];
int main()
{
freopen("cowtour.in","r",stdin);
freopen("cowtour.out","w",stdout);
int n;
scanf("%d",&n);
int i,j,k;
for(i=0;i<n;i++)
{
scanf("%d %d",&v[i].x,&v[i].y);
}
memset(bing,-1,152*sizeof(int));
scanf("%c",&fei);
//构建原始的图信息,包括两点距离计算,并查集产生
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%c",&flag[i][j]);
if(flag[i][j]=='1')
{
if(bing[i]==-1&&bing[j]==-1)
{
bing[j]=i;
bing[i]=i;
}
else
{
if(bing[i]==-1)
{
bing[i]=bing[j];
}
else if(bing[j]==-1)
{
bing[j]=bing[i];
}
else
{
for(k=0;k<n;k++)
{
if(bing[k]==bing[j])
bing[k]=bing[i];
}
}
}
ma[i][j]=sqrt((v[i].x-v[j].x)*(v[i].x-v[j].x)+(v[i].y-v[j].y)*(v[i].y-v[j].y));
}
else {
if(i!=j)
ma[i][j]=INT_MAX;
else
ma[i][j]=0;
}
}
scanf("%c",&fei);
}
for(i=0;i<n;i++)
if(bing[i]==-1)
bing[i]=i;
//Floyd算法最短路
for(k=0;k<n;k++)
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
ma[i][j]=std::min(ma[i][j],ma[i][k]+ma[k][j]);
}
//连通子图的每个点对应的直径(不一定是最大的)
for(i=0;i<n;i++)
{
d[i]=0;
for(j=0;j<n;j++)
{
if(ma[i][j]!=INT_MAX)
d[i]=std::max(d[i],ma[i][j]);
}

}
k=5;
double ans=INT_MAX;
//每个子图的最大直径
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
if(bing[i]==bing[j])
{
dd[bing[i]]=std::max(dd[bing[i]],ma[i][j]);
}
}
//尝试连接两个牧场,比较新直径和两个原始直径,最大者即为新的直径
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
if(bing[i]!=bing[j])
{
double temp;
temp=std::max(std::max(d[i]+d[j]+sqrt((v[i].x-v[j].x)*(v[i].x-v[j].x)+(v[i].y-v[j].y)*(v[i].y-v[j].y)),dd[bing[i]]),dd[bing[j]]);
ans=std::min(temp,ans);
}
}
printf("%.6f\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  usaco