牛的旅行 Cow Tours

来源:互联网 发布:阿依莲正品淘宝折扣店 编辑:程序博客网 时间:2024/06/05 06:24

P1522 牛的旅行 Cow Tours
题目概述:有的路径连接一些特定的牧区。一片所有连通的牧区称为一个牧场。但是就目前而言,你能看到至少有两个牧区通过任何路径都不连通。在牧场里添加一条路径(注意,恰好一条)。对这条路径有以下限制:一个牧场的直径就是牧场中最远的两个牧区的距离(本题中所提到的所有距离指的都是最短的距离)。请编程找出一条连接两个不同牧场的路径,使得连上这条路径后,这个更大的新牧场有最小的直径。输出在所有牧场中最小的可能的直径。
数据规模:N (1 <= N <= 150),X,Y (0 <= X ,Y<= 100000)
思路:这个题首先要预处理距离,用勾股定理,然后考虑到N的值比较小(事实上小于300就可以了),我们考虑用O(N^3)的Floyd算法,然后如果暴力枚举一次就是O(N^2)*O(N^3)的时间,就算N再小也不能用这种算法,所以考虑是求一个最值,所以用最大值来记录,这样时间变为O(N^2),就可以过了。
代码:

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>#include<cmath>using namespace std;int x[155],y[155];double a[155][155];int temp;int i,j,k,n,t,m;double maxx,minn=10000000000;int b[155];double c[155][155];int rr(){    int ans=0,f=1;    char ch=getchar();    while(ch<'0'||ch>'9')    {        if(ch=='-')            f=-1;        ch=getchar();    }    while(ch>='0'&&ch<='9')    {        ans*=10;        ans+=ch-'0';        ch=getchar();    }    return ans*f;}double dis(int xx,int yy){    return sqrt((x[xx]-x[yy])*(x[xx]-x[yy])    +(y[xx]-y[yy])*(y[xx]-y[yy]));}void solve(){    for(int i=1;i<=n;i++)    for(int j=1;j<=n;j++)    {        for(int k=1;k<=n;k++)        {        if(a[i][j]>a[i][k]+a[k][j])        a[i][j]=a[i][k]+a[k][j];        }    }    for(int i=1;i<=n;i++)    for(int j=1;j<=n;j++)    {        for(int k=1;k<=n;k++)        {        if(a[i][j]>a[i][k]+a[k][j])        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][j]!=1000000000)    maxx=max(maxx,a[i][j]);    for(int i=1;i<=n;i++)    for(int j=1;j<=n;j++)    a[i][j]=c[i][j];}int main(){    n=rr();    for(i=1;i<=n;i++)    for(j=1;j<=n;j++)    a[i][j]=1000000000;    char ch;    for(i=1;i<=n;i++)    x[i]=rr(),y[i]=rr();    for(i=1;i<=n;i++)    for(j=1;j<=n;j++)    {        cin>>ch;        if(ch=='1')        a[i][j]=a[j][i]=dis(i,j);    }    for(i=1;i<=n;i++)    a[i][i]=0;    for(i=1;i<=n;i++)    for(j=1;j<=n;j++)    for(k=1;k<=n;k++)    {        if(a[i][j]>a[i][k]+a[k][j])        a[i][j]=a[i][k]+a[k][j];    }    for(i=1;i<=n;i++)    for(j=1;j<=n;j++)    c[i][j]=a[j][i];    for(int i=1;i<=n;i++)    for(int j=1;j<i;j++)    {        if(a[i][j]==1000000000)        {            maxx=0;            a[i][j]=a[j][i]=dis(i,j);            solve();            minn=min(minn,maxx);            a[i][j]=a[j][i]=1000000000;        }    }    printf("%.6f",minn);    return 0;}/**/

这里写图片描述

原创粉丝点击