洛谷 P1661 扩散

该博客介绍了洛谷P1661题目的扩散问题,探讨了如何判断平面上的点在经过一定时间后形成一个连通块。题目要求根据点的坐标和扩散规则,找出最早的时间点使所有点相互连通。博客提供了三种解法,包括曼哈顿距离的计算、最小生成树和Floyd算法,并给出了做法一的代码实现。数据规模限制为1≤N≤50, 1≤X[i],Y[i]≤10^9。" 133144142,19671681,浙江省口腔医院的超声波辅助树脂填充技术,"['医疗技术', '口腔医学', '牙齿修复', '超声波应用']
摘要由CSDN通过智能技术生成

题目描述

一个点每过一个单位时间就会向四个方向扩散一个距离,如图。

这里写图片描述

两个点a、b连通,记作e(a,b),当且仅当a、b的扩散区域有公共部分。连通块的定义是块内的任意两个点u、v都必定存在路径e(u,a0),e(a0,a1),…,e(ak,v)。给定平面上的n给点,问最早什么时刻它们形成一个连通块。

输入输出格式
输入格式:

第一行一个数n,以下n行,每行一个点坐标。

【数据规模】

对于20%的数据,满足1≤N≤5; 1≤X[i],Y[i]≤50;

对于100%的数据,满足1≤N≤50; 1≤X[i],Y[i]≤10^9。

输出格式:

一个数,表示最早的时刻所有点形成连通块。

输入输出样例

输入样例#1:
2
0 0
5 5

输出样例#1:
5


【分析】
做法一:(曼哈顿距离+1)/2+二分答案
做法二:最小生成树
做法三:floyd

提供做法一代码


【代码】

#include<iostream>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int mxn=55;
int n,px[mxn],py[mxn],dis[mxn][mxn];
bool color[mxn],con[mxn][mxn];
inline void dfs(int u,int fa)
{
    int i,j;
    color[u]=1;
    fo(i,1,n) if(con[i][u] && i!=fa && !color[i])
      dfs(i,u);
}
inline bool ok(int mid)
{
    int i,j;
    memset(color,0,sizeof color);
    memset(con,0,sizeof con);
    fo(i,1,n) fo(j,1,n) if(dis[i][j]<=mid) con[i][j]=con[j][i]=1;  
    dfs(1,0);
    fo(i,1,n) if(!color[i]) return 0;
    return 1;
}
int main()
{
//  freopen("ppg.in","r",stdin);
//  freopen("ppg.out","w",stdout);
    int i,j,mx=0;
    scanf("%d",&n);
    fo(i,1,n)
      scanf("%d%d",&px[i],&py[i]);
    fo(i,1,n) fo(j,1,n)
      dis[i][j]=(abs(px[i]-px[j])+abs(py[i]-py[j])+1)/2,mx=max(mx,dis[i][j]);
    int l=1,r=mx;
    while(l<r)
    {
        int mid=(l+r)/2;
        if(ok(mid)) r=mid;
        else l=mid+1;
    }
    printf("%d\n",l);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值