C 一本通 1 2 練習 2 擴散

2021-10-05 11:56:23 字數 2341 閱讀 2113

一本通題庫-1437

libreoj-10015

計蒜客-t1882

vjudge

乙個點每過乙個單位時間就會向 4 個方向擴散乙個距離,如圖所示:兩個點 a 、b 連通,記作 e(a

,b)e(a,b)

e(a,b)

,當且僅當 a 、b 的擴散區域有公共部分。連通塊的定義是塊內的任意兩個點 u、v 都必定存在路徑 e(u

,a0)

,e(a

0,a1

),…e

(ak,

v)e(u,a_0),e(a_0,a_1),…e(a_k,v)

e(u,a0

​),e

(a0​

,a1​

),…e

(ak​

,v)。

給定平面上的 n 個點,問最早什麼時候它們形成乙個連通塊。

第一行乙個數 n ,以下 n 行,每行乙個點座標。

輸出僅乙個數,表示最早的時刻所有點形成連通塊。

2

0 05 5

5
對於 20

%20\%

20% 的資料,滿足 1≤n

≤5,1

≤xi,

yi≤50

1≤n≤5,1≤x_i,y_i≤50

1≤n≤5,

1≤xi

​,yi

​≤50

;對於 100

%100\%

100%

的資料,滿足 1≤n

≤50,1

≤xi,

yi≤1

091≤n≤50,1≤x_i,y_i≤10^9

1≤n≤50

,1≤x

i​,y

i​≤1

09。

二分答案,並用並查集維護是否聯通。

詳細點說就是每次暴力列舉兩個點,判斷在當前時間是否聯通,如果聯通就在並查集裡連線。

#pragma gcc optimize(3,"ofast","inline")

#pragma g++ optimize(3,"ofast","inline")

#include

#include

#include

#include

#include

#define ri register int

#define re(i,a,b) for(ri i=a; i<=b; i++)

#define ms(i,a) memset(a,i,sizeof(a))

#define max(a,b) (((a)>(b)) ? (a):(b))

#define min(a,b) (((a)

using

namespace std;

typedef

long

long ll;

const

int n=55;

const

int inf=

1e9;

struct node a[n]

;int n;

int fa[n]

;int d[n]

[n];

inline

intgetfa

(int x)

inline

intcheck

(int x,

int y)

inline

voidf(

int l,

int r)

int mid=

(l+r)

>>1;

for(

int i=

1; i<=n; i++

) fa[i]

=i;int k=n;

for(

int i=

1; i<=n; i++

)for

(int j=i+

1; j<=n; j++)if

(d[i]

[j]<=

(mid<<1)

)if(check

(i,j)

) k--;if

(k==1)

f(l,mid)

;else

f(mid,r);}

intmain()

一本通 1 2 練習 2 擴散

題目link 這道題雖說是二分裡的,但是我沒用二分的做法。首先我的想法是直接找到任意兩點之間的最大距離即可,但是後來寫完交上去發現不對,之後分析了一下發現兩個點成為同乙個連通塊是可以通過另外乙個連通塊更新距離的,因為另乙個連通塊也可以擴散,有點類似 floyd 更新完之後可以直接像第乙個思路一樣算了...

10016 一本通 1 2 練習 3 燈泡

題目描述 原題來自 zoj 3203 相比 wildleopard 的家,他的弟弟 mildleopard 比較窮。他的房子是狹窄的而且在他的房間裡面僅有乙個燈泡。每天晚上,他徘徊在自己狹小的房子裡,思考如何賺更多的錢。有一天,他發現他的影子的長度隨著他在燈泡和牆壁之間走到時發生著變化。乙個突然的想...

一本通 1 1 練習 2 數列分段

題目link 首先對於乙個序列,從 a 1 l 都符合最佳序列,假設對於第 l 1 個數,它放到從 l 1 r 的區間是一種最優的方法,並且它也可以放在從 1 l 1 這裡,那麼根據貪心,它放到 1 l 1 的序列中是合法的,而且也是一種最優方案。因此,這道題只需要貪心 能將當前數往左放就往左放。1...