您的位置:首页 > 其它

CodeChef:Travel to all Points(二分 & 技巧)

2017-08-16 14:08 344 查看


思路:二分答案,O(n)验证,|p-x|+|q-y| >= d可互达,相当于

(P+Q)-(X+Y)>=D

(P+Q)-(X+Y)<=-D

(P-Q)-(X-Y)>=D

(P-Q)-(X-Y)<=-D

任一种情况都可互达,那么设置两个数组分别对x+y和x-y排序,BFS看是否能够到达所有点即可,参考作者题解。

# include <bits/stdc++.h>
# define mp make_pair
using namespace std;
typedef long long LL;
const int maxn = 1e6+30;
const int INF = 2e9+10;
int n, x1[maxn], x2[maxn], vis[maxn], q[maxn<<1];
pair<int,int>x3[maxn], x4[maxn];

bool check(int d)
{
memset(vis, 0, sizeof(vis));
int l=0, r=0, x3_h=0, x3_t=n-2, x4_h=0, x4_t=n-2;
q[r++] = 0;
vis[0] = 1;
auto add = [&](int v)
{
q[r++] = v;
vis[v] = 1;
while(x3_h <= x3_t && vis[x3[x3_t].second]) --x3_t;
while(x3_h <= x3_t && vis[x3[x3_h].second]) ++x3_h;
while(x4_h <= x4_t && vis[x4[x4_h].second]) ++x4_h;
while(x4_h <= x4_t && vis[x4[x4_t].second]) --x4_t;
};
while(l < r)
{
int u = q[l++];
while(x3_h <= x3_t && x1[u] - x3[x3_t].first <= -d) add(x3[x3_t].second);
while(x3_h <= x3_t && x1[u] - x3[x3_h].first >= d) add(x3[x3_h].second);
while(x4_h <= x4_t && x2[u] - x4[x4_h].first >= d) add(x4[x4_h].second);
while(x4_h <= x4_t && x2[u] - x4[x4_t].first <= -d) add(x4[x4_t].second);

}
return l == n;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int a, b, i=0; i<n; ++i)
{
scanf("%d%d",&a,&b);
x1[i] = a+b;
x2[i] = a-b;
if(i)
{
x3[i-1] = mp(x1[i], i);
x4[i-1] = mp(x2[i], i);
}
}
sort(x3, x3+n-1);
sort(x4, x4+n-1);
int l=0, r=INF;
while(l <= r)
{
int m = (LL)l+r>>1;
if(check(m)) l = m+1;
else r = m-1;
}
printf("%d\n",r);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: