USACO-Cow Tours

来源:互联网 发布:手机淘宝怎样添加好友 编辑:程序博客网 时间:2024/05/29 13:44

来源:http://ace.delos.com/usacoprob2?a=ecro6SKAJN4&S=cowtour

看到题目的数据范围就知道这题应该用O(n^3)的算法做了,明显图论中Floyd算法就符合要求。

算法:

1.floyd求出任意两点的距离;

2.对于连通块A和连通块B,添加一条边e(u,v),把A和B联通,新的连通块称为C,则:

          dist[C]=dist[A][u]+dist[B][v]+e(u,v)         //dist[C]表示连通块C的最大距离,dist[A][u]表示连通块A中的点离u点的最远距离

3.枚举边e(u,v),找出最小的最大距离

具体的程序如下:

/*ID:ay27272PROG:cowtourLANG:C++*/#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <math.h>using namespace std;#define MINN 0.0001struct node{    int x,y;    node()    {        x=y=0;    }    node(int a,int b)    {        x=a; y=b;    }};double a[155][155];struct node d[155];int n;double sqrtt(int a,int b)          //求出两点的距离{    double x1=d[a].x-d[b].x;    double x2=d[a].y-d[b].y;    return sqrt(x1*x1+x2*x2);}void floyd(){    for (int k=1;k<=n;k++)       //floyd算法模板        for (int i=1;i<=n;i++)        if (i!=k)            for (int j=1;j<=n;j++)            if (i!=j && k!=j)            if (a[i][k]>MINN && a[k][j]>MINN &&                (a[i][j]-a[i][k]-a[k][j]>MINN || a[i][j]<MINN))                a[i][j]=a[i][k]+a[k][j];    for (int i=1;i<=n;i++)       //记录每个点在其连通块中与其它点的最大距离        for (int j=1;j<=n;j++)        if (a[i][0]<a[i][j])            a[i][0]=a[i][j];}int main(){    freopen("cowtour.in","r",stdin);    freopen("cowtour.out","w",stdout);    int xx,yy;    scanf("%d",&n);    for (int i=1;i<=n;i++)    {        scanf("%d%d\n",&xx,&yy);        d[i]=node(xx,yy);    }    char s[200];    for (int i=1;i<=n;i++)    {        gets(s);        for (int j=0;j<n;j++)        {            if (s[j]=='0') a[i][j+1]=a[j+1][i]=0.0;            else a[i][j+1]=a[j+1][i]=sqrtt(i,j+1);        }    }    floyd();    double maxx=10000000.0,k;    for (int i=1;i<=n;i++)       //枚举边e(i,j)        for (int j=1;j<=n;j++)        if (i!=j)        {            k=sqrtt(i,j)+a[i][0]+a[j][0];            if (a[i][j]<MINN && k<maxx)            maxx=k;        }    for (int i=1;i<=n;i++)        //这一步不能省,因为有可能添加边后最大的距离并不在这个新的连通块中        maxx=max(maxx,a[i][0]);    printf("%.6lf\n",maxx);    return 0;}
原创粉丝点击