https://acm.hdu.edu.cn/showproblem.php?pid=7058
平面坐标一堆点滴墨水,墨水每秒扩散0.5,求什么时候全部相连。
太简单了原本不想写这题题解的,但是这题先卡我二分又卡我kruskal所以我来抱怨一句(
不难看出最终就是求完全图的生成树的最长边最小。依据kruskal算法不难发现这条边就是最小生成树的最长边,因此转化成为求最小生成树即可。
prim算法可以通过该题,加不加堆优化都行,我试了下速度还都一样,放个没堆优化的版本(
#include<cmath> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N=5005; const ll INF=9e18; inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch=='-';ch=getchar();} while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } struct node{ ll x,y; }a[N]; ll dis(int i,int j){ return (a[i].x-a[j].x)*(a[i].x-a[j].x)+ (a[i].y-a[j].y)*(a[i].y-a[j].y); } int n; bool vis[N]; ll d[N][N],w[N]; ll prim(){ for(int i=1;i<=n;i++)w[i]=INF,vis[i]=0; int u=1;vis[u]=1;w[u]=0; for(int v=1;v<=n;v++){ if(!vis[v]&&w[v]>d[u][v]){ w[v]=d[u][v]; } } int num=0;ll ans=0; while(++num<n){ ll minn=INF; for(int v=1;v<=n;v++){ if(!vis[v]&&minn>w[v]){ minn=w[v]; u=v; } } vis[u]=1;ans=max(ans,minn); for(int v=1;v<=n;v++){ if(!vis[v]&&w[v]>d[u][v]){ w[v]=d[u][v]; } } } return ans; } int main(){ int T=read(); while(T--){ n=read(); for(int i=1;i<=n;i++){ a[i].x=read();a[i].y=read(); for(int j=1;j<n;j++){ d[i][j]=d[j][i]=dis(i,j); } } printf("%lld ",prim()); } return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++