洛谷1522 牛的旅行 floyed
阿新 • • 發佈:2018-12-24
點少,標準的floyed。先用floyed更新出任意兩點之間的最短距離。用並查集標記在同一牧場的的點。最後列舉兩個不同牧場的點之間的距離len3,以及各自和自己牧場中最遠的距離len1,len2.我們求的結果就是最小的(len1+len2+len3)。
然後第七個點一直過不去。後來發現,少考慮了一種情況,就是可能兩個原牧場中的某一個直徑可能大於len1+len2+len3。。。。。。。。。。找了三個小時
#include <bits/stdc++.h> using namespace std; #define inf 0x3f3f3f3f #define res register int const int maxn=155; char G[maxn][maxn]; double dis[maxn][maxn]; int fa[maxn]; int N; struct Node{ double x,y; }node[maxn]; double cal(int a,int b){ return sqrt(abs(node[a].x-node[b].x)*abs(node[a].x-node[b].x)+abs(node[a].y-node[b].y)*abs(node[a].y-node[b].y)); } int find(int x){ if(x==fa[x]) return x; else return fa[x]=find(fa[x]); } void unit(int x,int y){ x=find(x); y=find(y); if(x!=y) fa[x]=y; return; } void init() { cin>>N; for(res i=1;i<=N;i++){ fa[i]=i; scanf("%lf%lf",&node[i].x,&node[i].y); } for(res i=1;i<=N;i++){ char temp[maxn]; scanf("%s",temp); sprintf(G[i],"#%s",temp); } for(res i=1;i<=N;i++) for(res j=1;j<=N;j++) dis[i][j]=inf; for(res i=1;i<=N;i++){ for(res j=1;j<i;j++){ if('1'==G[i][j]){ unit(j,i); dis[i][j]=dis[j][i]=cal(i,j); } } } for(res i=1;i<=N;i++) dis[i][i]=0; } void floyed() { for(res k=1;k<=N;k++) for(res i=1;i<=N;i++) for(res j=1;j<=N;j++) dis[i][j]=dis[j][i]=min(dis[i][j],dis[i][k]+dis[k][j]); } int main() { init(); floyed(); double len=inf; for(res i=1;i<=N;i++) for(res j=i+1;j<=N;j++){ double len1=-inf,len2=-inf,len3=-inf;//len1表示的是第一個牧場到該點的距離 len2是第二個 len3表示的是兩點之間的距離 if(find(i)!=find(j)){ len3=cal(i,j); //開始找第i個點所在牧場裡面所有的點到i點最大的距離 for(res k=1;k<=N;k++) if(find(k)==find(i)) len1=max(len1,dis[i][k]); //開始找第j個點所在牧場裡面所有的點到j點最大的距離 for(res k=1;k<=N;k++) if(find(k)==find(j)) len2=max(len2,dis[j][k]); len=min(len,len1+len2+len3); } } printf("%.6lf",len); return 0; }