usaco Cow Tours

来源:互联网 发布:oracle数据库密码忘了 编辑:程序博客网 时间:2024/06/10 12:27

多源最短路

弗洛伊德算法+并查集

很适合用来训练图论的思维

/*ID:zhdxzwj1LANG: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;}

0 0
原创粉丝点击