USACO Section 2.4 Cow Tours - 考虑要全面阿...

这道题最值得注意的是牧场数>=2...也就是说把两个联通图相连后得到的新牧场大小并不一定是最大的..可能还有另外一个没连的直径更长...

其他的..用并查集来判断是否在一个联通图里..用Floyd求两点的最短路径~~

进入第三章了~~


Program:

/* ID: zzyzzy12 LANG: C++ TASK: cowtour */ #include<iostream> #include<istream> #include<stdio.h> #include<string.h> #include<math.h> #include<stack> #include<algorithm> #include<queue> #define oo 2000000000 using namespace std; struct node { int y,x; }point[155]; double p[155][155],ans,ans2,sum[155]; int n,father[155]; bool getdata() { char c=' '; while (c!='1' && c!='0') c=getchar(); if (c=='1') return true; return false; } double dis(node a,node b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } int getfather(int i) { if (father[i]==i) return i; return father[i]=getfather(father[i]); } void Floyd() { int k,i,j; for (k=1;k<=n;k++) for (i=1;i<=n;i++) for (j=1;j<=n;j++) if (p[i][j]>p[i][k]+p[k][j]) p[i][j]=p[i][k]+p[k][j]; return; } int main() { freopen("cowtour.in","r",stdin); freopen("cowtour.out","w",stdout); scanf("%d",&n); int i,j,k; for (i=1;i<=n;i++) { scanf("%d%d",&point[i].x,&point[i].y); p[i][i]=0; father[i]=i; } for (i=1;i<=n;i++) for (j=1;j<=n;j++) if (getdata()) { p[i][j]=dis(point[i],point[j]); father[getfather(i)]=getfather(j); } else if (i!=j) p[i][j]=oo; Floyd(); memset(sum,0,sizeof(sum)); for (i=1;i<=n;i++) for (j=1;j<=n;j++) if (getfather(i)==getfather(j) && p[i][j]>sum[i]) sum[i]=p[i][j]; ans2=0; for (i=1;i<=n;i++) if (ans2<sum[i]) ans2=sum[i]; ans=oo; for (i=1;i<=n;i++) for (j=1;j<=n;j++) if (father[i]!=father[j] && ans>sum[i]+sum[j]+dis(point[i],point[j])) ans=sum[i]+sum[j]+dis(point[i],point[j]); if (ans2>ans) ans=ans2; printf("%.6lf\n",ans); return 0; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值