Luogu P1265 公路修建
一眼看去,就是一道MST的模板题。
然后果断准备跑Kruskal,然后5个TLE。
Kruskal复杂度对于这个完全图要O(n^2*logn^2),快排就会导致超时。
然后打了刚学的Prim。朴素O(n^2)卡过。
Prim的思想很简单,用dis数组来存目前的MST(初始时只有一个节点)到其他点的最小距离,f数组记录是否使用,方法很巧妙。
总觉得Prim和Dijkstra很相像
思想像,代码也像。
CODE
#include<cstdio> #include<cmath> #include<cstring> using namespace std; const int N=5005; double dis[N],x[N],y[N],ans; int n,i,j; bool f[N]; inline double calc(double a,double b,double c,double d) { return sqrt((a-b)*(a-b)+(c-d)*(c-d)); } inline double min(double a,double b) { return a<b?a:b; } int main() { scanf("%d",&n); for (i=1;i<=n;++i) scanf("%lf%lf",&x[i],&y[i]); for (i=1;i<=n;++i) dis[i]=calc(x[1],x[i],y[1],y[i]); memset(f,true,sizeof(f)); f[1]=0; for (i=1;i<n;++i) { double MIN=0x7ffffff; int k=0; for (j=1;j<=n;++j) if (f[j]&&dis[j]<MIN) MIN=dis[j],k=j; ans+=MIN; f[k]=0; for (j=1;j<=n;++j) if (f[j]) dis[j]=min(dis[j],calc(x[k],x[j],y[k],y[j])); } printf("%.2lf",ans); return 0; }
辣鸡老年选手AFO在即