题目
从Freddy到Fiona的路径中,一条路径最大的边的最小值
分析
其实就是变种floyd
f
[
i
]
[
j
]
=
m
i
n
(
f
[
i
]
[
j
]
,
m
a
x
(
f
[
i
]
[
k
]
,
f
[
k
]
[
j
]
)
)
f[i][j]=min(f[i][j],max(f[i][k],f[k][j]))
f[i][j]=min(f[i][j],max(f[i][k],f[k][j]))最大值最小
首先第一波福利(n^3)
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int x[201],y[201],n,m;
double a[201][201];
int o(int t){return t*t;}
int main(){
scanf("%d",&n);
while (n){ m++;
for (int i=1;i<=n;i++){
scanf("%d%d",&x[i],&y[i]);
for (int j=1;j<=i-1;j++)
a[i][j]=sqrt((double)o(x[i]-x[j])+(double)o(y[i]-y[j])),a[j][i]=a[i][j];
}
for (int k=1;k<=n;k++)
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
a[i][j]=min(a[i][j],max(a[i][k],a[k][j]));//floyd
printf("Scenario #%d\n",m);
printf("Frog Distance = %.3lf\n\n",a[1][2]);
scanf("%d",&n);
}
return 0;
}//93ms
so想到了吗(最小生成树)
Kruskal is coming
(有点丑,请见谅,不管黑猫白猫,抓住老鼠就是好猫)
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
struct bcj{
int u,v;
double w;
}a[40001];
int o(int t){return t*t;}
bool cmp(bcj x,bcj y){return x.w<y.w;}
int n,m,tt,f[40001],x[201],y[201];
int father(int x){if (f[x]==x) return x; else return f[x]=father(f[x]);}
int main(){
scanf("%d",&n);
while (n){ m++; tt=0; double ans=0;
for (int i=1;i<=n;i++) f[i]=i,scanf("%d%d",&x[i],&y[i]);
for (int i=1;i<=n;i++)
for (int j=i+1;j<=n;j++)
a[++tt].u=i,a[tt].v=j,
a[tt].w=sqrt(o(x[i]-x[j])+o(y[i]-y[j]));
sort(a+1,a+1+tt,cmp);//快排保证最优
for (int i=1;i<=tt;i++){
int fa=father(a[i].u);//祖先
int fb=father(a[i].v);//祖先
if (fa!=fb){
if (fa<fb) f[fb]=fa;//合并
else f[fa]=fb;(用小的)
if (father(1)==father(2)){//如果两个石头祖先相同
ans=a[i].w;
break;//直接退出
}
}
}
printf("Scenario #%d\n",m);
printf("Frog Distance = %.3lf\n\n",ans);
scanf("%d",&n);
}
return 0;
}15ms