HDU7058:Ink on paper——题解

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\n",prim());
    }
    return 0;
}

+++++++++++++++++++++++++++++++++++++++++++

 +本文作者:luyouqi233。               +

 +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

posted @ 2021-08-12 17:58  luyouqi233  阅读(244)  评论(0编辑  收藏  举报