题面



$ solution: $

某蒟蒻的心路历程:

这一题第一眼感觉很奇怪

带障碍物的图,最大的集装箱?

首先想到的就是限制我集装箱大小条件的是什么:

如果我要在某一个点上放一个集装箱且使它最大,

那就相当于求这一个点往外扩出去的最大正方形。

然后考虑从一个点到与它相邻的点移动时最大的箱子,

这不就是这两个点的最大正方形中较小的那一个吗?

于是考虑把所有点上的最大正方形都求出来,这个n^2即可

然后我就是要求两个点之间所有路径上的最小的那个最大正方形了

仔细一想,嗯?,这不就是货车运输吗?难道我要切题了?

但毕竟被虐的太多了,还是理智的看一遍吧

哇,边数最多可以达到1000000条,我记得火车运输范围只有10000来着?

我靠,要凉啊,算了直接写暴力得了!(然而,……..)

这一道题,仔细审一下题面我们可以发现:在每一个位置上箱子都有一个初始大小,而它如果要移动到与它中心相邻的某一个点上,他的大小又会受到它要移动到的那个点。所以我们可以先跑一遍BFS来求出没一点的初始最大正方形(这个我们可以反过来,从障碍物出发向四周扩展,每个点只会进队一次,复杂度完全可以接受)。然后我们对任何一对相邻的点连边,边权即为两个中最大正方形较小的那一个。这样我们如果要求两条点可以运输的最大正方形,就是求他们之间所有路径中最小权值最大的那一个,而这不就是货车运输吗????(好吧,其实LCA十分容易被卡,所以建议用树链剖分)



$ code: $

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set> #define ll long long
#define db double
#define inf 0x7fffffff
#define rg register int using namespace std; struct su{
int x,y,v;
bool operator <(su x){return v>x.v;}
}b[2000005]; struct pi{
int x,y,v;
}t[2000005]; struct ya{
int to,v,next;
}d[2000005]; int n,m,tt,top,ttt,xx,yy,ans;
int a[1000005];
int tou[1000005];
int s[1005][1005];
bool k[1005][1005];
char c[1005];
bool vis[1000005];
int dp[1000005];
int lg[1000005];
int f[1000005][20];
int st[1000005][20]; inline int qr(){
char ch;
while((ch=getchar())<'0'||ch>'9');
int res=ch^48;
while((ch=getchar())>='0'&&ch<='9')
res=res*10+(ch^48);
return res;
} inline int max(int x,int y){return x<y?y:x;}
inline int min(int x,int y){return x<y?x:y;}
inline int minn(int x,int y,int z){return x<y?(x<z?x:z):(y<z?y:z);}
inline int get(int x){return x==a[x]?x:a[x]=get(a[x]);} inline void qw(int x){
printf("(%d %d)",(x%n==0?x/n-1:x/n),(x%n==0?n:x%n));
} inline void yu(){
int i=0,x,y,v;
while(++i<=tt){
x=t[i].x;y=t[i].y;v=t[i].v;
if(!k[x+1][y+1]&&x+1<=n&&y+1<=n) s[x+1][y+1]=v, k[x+1][y+1]=1, t[++tt]=pi{x+1,y+1,v+1};
if(!k[x+1][y]&&x+1<=n&&y<=n) s[x+1][y]=v, k[x+1][y]=1, t[++tt]=pi{x+1,y,v+1};
if(!k[x+1][y-1]&&x+1<=n&&0<y-1) s[x+1][y-1]=v, k[x+1][y-1]=1, t[++tt]=pi{x+1,y-1,v+1};
if(!k[x][y+1]&&0<x&&y+1<=n) s[x][y+1]=v, k[x][y+1]=1, t[++tt]=pi{x,y+1,v+1};
if(!k[x][y-1]&&0<x&&0<y-1) s[x][y-1]=v, k[x][y-1]=1, t[++tt]=pi{x,y-1,v+1};
if(!k[x-1][y+1]&&0<x-1&&y+1<=n) s[x-1][y+1]=v, k[x-1][y+1]=1, t[++tt]=pi{x-1,y+1,v+1};
if(!k[x-1][y]&&0<x-1&&y<=n) s[x-1][y]=v, k[x-1][y]=1, t[++tt]=pi{x-1,y,v+1};
if(!k[x-1][y-1]&&0<x-1&&0<y-1) s[x-1][y-1]=v, k[x-1][y-1]=1, t[++tt]=pi{x-1,y-1,v+1};
}
} inline bool dfs(int i,int fa,int dp){
for(rg j=tou[i];j;j=d[j].next){
int to=d[j].to;
if(to==fa)continue;
//qw(i);cout<<"=>";qw(to);;
if(to==yy){
ans=min(dp,d[j].v);
return 1;
}
if(dfs(to,i,min(dp,d[j].v)))return 1;
}return 0;
} inline void lca(int x,int dep){
dp[x]=dep; vis[x]=1;
for(rg i=0;i<19;++i)
f[x][i+1]=f[f[x][i]][i];
for(rg i=0;i<19;++i)
st[x][i+1]=min(st[x][i],st[f[x][i]][i]);
for(rg i=tou[x];i;i=d[i].next){
int to=d[i].to;
if(to==x||vis[to])continue;
f[to][0]=x;
st[to][0]=d[i].v;
lca(to,dep+1);
}
} inline int find(int x,int y){
if(dp[x]<dp[y])swap(x,y);
ans=100001;
for(rg i=19;i>=0;--i){
if(dp[f[x][i]]>=dp[y]){
ans=min(st[x][i],ans);
x=f[x][i];
}
if(x==y)return ans;
}
for(rg i=19;i>=0;--i){
if(f[x][i]!=f[y][i]){
ans=minn(ans,st[x][i],st[y][i]);
x=f[x][i];y=f[y][i];
}
}
return minn(ans,st[x][0],st[y][0]);
} int main(){
//freopen("B.in","r",stdin);
//freopen("B.out","w",stdout);
n=qr();
for(rg i=1;i<=n;++i){
scanf("%s",c+1);
for(rg j=1;j<=n;++j)
if(c[j]!='.')k[i][j]=1,t[++tt]=pi{i,j,1};
}
for(rg i=0;i<=n+1;++i){
k[i][0]=1;t[++tt]=pi{i,0,1};
k[i][n+1]=1;t[++tt]=pi{i,n+1,1};
k[0][i]=1;t[++tt]=pi{0,i,1};
k[n+1][i]=1;t[++tt]=pi{n+1,i,1};
}yu();
for(rg i=1;i<=n;++i)
for(rg j=1;j<n;++j)
b[++top]=su{i*n+j-n,i*n+j+1-n,min(s[i][j],s[i][j+1])};
for(rg i=1;i<n;++i)
for(rg j=1;j<=n;++j)
b[++top]=su{i*n+j-n,i*n+j,min(s[i][j],s[i+1][j])};
sort(b+1,b+top+1);
for(rg i=1;i<=n*n;++i)a[i]=i;
for(rg i=1;i<=top;++i){
if(get(b[i].x)!=get(b[i].y)){
a[get(b[i].x)]=get(b[i].y);
d[++ttt]=ya{b[i].y,b[i].v,tou[b[i].x]};tou[b[i].x]=ttt;
d[++ttt]=ya{b[i].x,b[i].v,tou[b[i].y]};tou[b[i].y]=ttt;
}
}
m=qr(); lca(1,1);
for(rg i=1;i<=m;++i){
xx=qr()*n+qr()-n; yy=qr()*n+qr()-n;
int ans=find(xx,yy);
printf("%d\n",(!ans?0:ans*2-1));
}
return 0;
}

[CERC2016]机棚障碍 Hangar Hurdles(kruskal重构树+树上倍增)的更多相关文章

  1. LG3684 [CERC2016]机棚障碍 Hangar Hurdles

    题意 题目描述 你正在评估一些关于一个巨型飞机仓库的建设计划.飞机仓库的地面可以表示为n行n列的网格图,其中每个格子要么是空的,要么有障碍物.行从上到下依次被编号为1到n,列从左到右依次被编号为1到n ...

  2. BZOJ.4793.[CERC2016]Hangar Hurdles(Kruskal重构树 BFS)

    题目链接 \(Description\) 有一个\(n\times n\)的正方形网格,上面有若干障碍点.\(q\)次询问,每次询问把一个正方形箱子从\((x1,y1)\)推到\((x2,y2)\) ...

  3. Gym - 101173H Hangar Hurdles (kruskal重构树/最小生成树+LCA)

    题目大意:给出一个n*n的矩阵,有一些点是障碍,给出Q组询问,每组询问求两点间能通过的最大正方形宽度. 首先需要求出以每个点(i,j)为中心的最大正方形宽度mxl[i][j],可以用二维前缀和+二分或 ...

  4. 【BZOJ 3551】[ONTAK2010] Peaks加强版 Kruskal重构树+树上倍增+主席树

    这题真刺激...... I.关于Kruskal重构树,我只能开门了,不过补充一下那玩意还是一棵满二叉树.(看一下内容之前请先进门坐一坐) II.原来只是用树上倍增求Lca,但其实树上倍增是一种方法,L ...

  5. 洛谷 P3684 机棚障碍Hangar Hurdles [CERC2016] 图论

    正解: 解题报告: 传送门! 首先不难想到这题主要有两个问题需要解决,一个是预处理出各个点的箱子半径最大值,一个是求ans 然后分别港下QwQ 首先关于预处理要说下昂 预处理有三种方法,分别港下 第一 ...

  6. UVA1265 Tour Belt Kruskal重构树、倍增、树上差分

    题目传送门 题意:定义$Tour \, Belt$为某张图上的一个满足以下条件的点集:①点集中至少有$2$个点②任意两点互相连通③图上两个端点都在这个点集中的边的权值的最小值严格大于图上只有一个端点在 ...

  7. Kruskal 重构树小记

    其实也不是多难的知识点吧--学了一个中午+半个下午就把它学会了(做过那道 jxd 作业 CF571D 的应该比较好理解) Kruskal 重构树大概就是在正常 Kruskal 的时候,对于两个需要连边 ...

  8. 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1202  Solved: 321[Submit][Sta ...

  9. 洛谷P4768 [NOI2018]归程(Kruskal重构树)

    题意 直接看题目吧,不好描述 Sol 考虑暴力做法 首先预处理出从$1$到每个节点的最短路, 对于每次询问,暴力的从这个点BFS,从能走到的点里面取$min$ 考虑如何优化,这里要用到Kruskal重 ...

随机推荐

  1. python 抽象类与接口类

    几个类 实现的方法都一致的话 就继承同一个父类 在父类写一个公共方法 给子类使用

  2. BZOJ5338 [TJOI2018] Xor 【可持久化Trie树】【dfs序】

    题目分析: 很无聊的一道题目.首先区间内单点对应异或值的询问容易想到trie树.由于题目在树上进行,case1将路径分成两段,然后dfs的时候顺便可持久化trie树做询问.case2维护dfs序,对d ...

  3. Leapin' Lizards HDU - 2732 (恶心的建图。。)

    这道题其实不难...就是建图恶心了点....emm... 题意: 多源多汇 + 拆边 青蛙跳柱子, 每根柱子都有一定的承载能力, 青蛙跳上去之后柱子的承载能力就会减一,跳到边界就能活 跳不到就over ...

  4. MT【65】寻找零点

    已知$f(x)=3ax^2+2bx+b-a$($a,b$不同时为零). 求证:$f(x)$在$(-1,0)$内至少有一个零点. 证明:$f(-\frac{1}{3})f(-1)=-\frac{1}{3 ...

  5. 【 Gym - 101138J 】Valentina and the Gift Tree(树链剖分)

    BUPT2017 wintertraining(15) 4 D Gym - 101138J 数据 题意 n个节点的一棵树,每个节点的权值为g,q个询问,树上的节点U-V,求U到V的路径的最大子段和. ...

  6. oracle调用DLL

    具体步骤:1.创建Oracle Library  Create Library  AAA as  'C:\UserData\xuxia\TestProc\Debug\TestProc.dll' 可以通 ...

  7. android sqlite批量插入数据速度解决方案

    转自 http://hi.baidu.com/hfutonline/blog/item/62b1e4de8bdf4b2e5882dd28.html 最近在做android项目的时候遇到一个问题,应用程 ...

  8. 【POJ3694】Network

    题目大意:给定一个 N 个点,M 条边的无向图,支持 Q 次操作,每次可以向该无向图中加入一条边,并需要回答当前无向图中桥的个数. 题解:(暴力:Q 次 Tarjan) 先进行一次 Tarjan 求出 ...

  9. ACCESS与SQL Server下SQL Like 查询的不同

    在ACCESS中LIKE的用法Access里like的通配符用法是这样: “?”表示任何单一字符: “*”表示零个或多个字符: “#”表示任何一个数字 所以应该是: select * from dat ...

  10. mac burp suite https证书安装

    1. 下载burp suite 2.安装,设置并代理上 3. 打开http://burp并且下载证书 4. 点击打开选择始终信任并且导出桌面 5. 火狐打开设置至证书一栏[证书机构]导入切信任 6.大 ...