洛谷P1522 [USACO2.4]牛的旅行 Cow Tours
题目要求的是两个牧场的最小直径,数据给出不只是两个独立牧场而是至少两个
所以我们要去暴力枚举每个不属于同一牧场的直径的最小值
这里需要注意的是两个牧场连起来的直径不一定是连线后 i所在的最短路+j所在的最短路+dis(i,j);
例如
1 #include<bits/stdc++.h> 2 using namespace std; 3 const double inf=1e15; 4 const int N=200; 5 int x[N],y[N],field[N]; 6 double dis[N][N],dismx[N],field_max[N]; 7 int n; 8 double getdis(int i,int j) 9 { 10 return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); 11 } 12 void dfs(int x,int id) 13 { 14 field[x]=id; 15 for(int i=1;i<=n;i++) 16 { 17 if(!field[i]&&dis[x][i]!=inf) 18 dfs(i,id); 19 } 20 } 21 void floyd() 22 { 23 for(int k=1;k<=n;k++) 24 for(int i=1;i<=n;i++) 25 for(int j=1;j<=n;j++) 26 dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); 27 } 28 int main() 29 { 30 31 scanf("%d",&n); 32 for(int i=1;i<=n;i++) 33 scanf("%d%d",&x[i],&y[i]); 34 35 char ch[n+1]; 36 for(int i=1;i<=n;i++) 37 { 38 scanf("%s",ch+1); 39 for(int j=1;j<=n;j++) 40 { 41 if(i==j)dis[i][i]=0; 42 else dis[i][j]=inf; 43 if(ch[j]=='1')dis[i][j]=getdis(i,j); 44 } 45 } 46 floyd(); 47 int id=0; 48 for(int i=1;i<=n;i++) 49 if(!field[i])dfs(i,++id);//染色遍历确定集合; 50 51 for(int i=1;i<=n;i++) 52 for(int j=1;j<=n;j++) 53 { 54 if(dis[i][j]==inf)continue;//说明不同集合 55 dismx[i]=max(dismx[i],dis[i][j]);//i,j同一集合且获得i到其他点的最短路的最大路径;即i的直径 56 field_max[field[i]]=max(field_max[field[i]],dismx[i]);//获得同一个集合里的最大直径 57 } 58 double ans=inf; 59 for(int i=1;i<=n;i++) 60 for(int j=1;j<=n;j++) 61 { 62 if(field[i]!=field[j]) 63 { //如果不同集合,我们就加边,确定两个牧场的直径,对所有可行解取min; 64 ans=min(max({dismx[i]+dismx[j]+getdis(i,j),field_max[field[i]],field_max[field[j]]}),ans); 65 } 66 } 67 printf("%.6lf",ans); 68 return 0; 69 }

浙公网安备 33010602011771号