4242: 水壶

Time Limit: 50 Sec  Memory Limit: 512 MB
Submit: 1028  Solved: 261
[Submit][Status][Discuss]

Description

JOI君所居住的IOI市以一年四季都十分炎热著称。
IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物、原野、墙壁之一。建筑物的区域有P个,编号为1...P。
JOI君只能进入建筑物与原野,而且每次只能走到相邻的区域中,且不能移动到市外。
JOI君因为各种各样的事情,必须在各个建筑物之间往返。虽然建筑物中的冷气设备非常好,但原野上的日光十分强烈,因此在原野上每走过一个区域都需要1单位的水。此外,原野上没有诸如自动售货机、饮水处之类的东西,因此IOI市的市民一般都携带水壶出行。大小为x的水壶最多可以装x单位的水,建筑物里有自来水可以将水壶装满。
由于携带大水壶是一件很困难的事情,因此JOI君决定携带尽量小的水壶移动。因此,为了随时能在建筑物之间移动,请你帮他写一个程序来计算最少需要多大的水壶。
现在给出IOI市的地图和Q个询问,第i个询问(1<=i<=Q)为“在建筑物Si和Ti之间移动,最小需要多大的水壶?”,请你对于每个询问输出对应的答案。

Input

第一行四个空格分隔的整数H,W,P,Q,表示IOI市被分成了纵H*横W块区域,有P个建筑物,Q次询问。
接下来H行,第i行(1<=i<=H)有一个长度为W的字符串,每个字符都是’.’或’#’之一,’.’表示这个位置是建筑物或原野,’#’表示这个位置是墙壁。
接下来P行描述IOI市每个建筑物的位置,第i行(1<=i<=P)有两个空格分隔的整数Ai和Bi,表示第i个建筑物的位置在第Ai行第Bi列。保证这个位置在地图中是’.’
接下来Q行,第i行(1<=i<=Q)有两个空格分隔的整数Si和Ti,表示第i个询问为“在建筑物Si和Ti之间移动,最小需要多大的水壶?”

Output

输出Q行,第i行(1<=i<=Q)一个整数,表示在建筑物Si和Ti之间移动最小需要多大的水壶。
如果无法到达,输出-1。此外,如果不需要经过原野就能到达,输出0。

Sample Input

5 5 4 4
.....
..##.
.#...
..#..
.....
1 1
4 2
3 3
2 5
1 2
2 4
1 3
3 4

Sample Output

3
4
4
2

HINT

1<=H<=2000
1<=W<=2000
2<=P<=2*10^5
1<=Q<=2*10^5
1<=Ai<=H(1<=i<=P)
1<=Bi<=W(1<=i<=P)
(Ai,Bi)≠(Aj,Bj)(1<=i<j<=P)
1<=Si<Ti<=P(1<=i<=Q)

跟bzoj4144题一样。。不过由于每条边距离相等,所以我们要把优先队列换成普通队列来减少时间。我实在是口算不出来这个时间是多少,然后一开始优先队列一直过不了。看了人家ac代码是普通队列一改就过了。。。orz。不过时间也是挺极限的46s。反正过啦!

  1. #include<bits/stdc++.h>
  2. #define clr(x) memset(x,0,sizeof(x))
  3. #define clr_1(x) memset(x,-1,sizeof(x))
  4. #define INF 0x3f3f3f3f
  5. #define LL long long
  6. #define pb push_back
  7. #define mod 1000000007
  8. #define ls(i) (i<<1)
  9. #define rs(i) (i<<1|1)
  10. #define mp make_pair
  11. #define fi first
  12. #define se second
  13. using namespace std;
  14. const int N=2e3+;
  15. const int M=2e5+;
  16. typedef pair<int,int> pii;
  17. typedef pair<LL,pii> plii;
  18. queue<pii> que;
  19. int mart[N][N];
  20. char s[N];
  21. LL dis[N][N];
  22. int pre[N][N];
  23. bool vis[N][N];
  24. struct edge
  25. {
  26. int u,v;
  27. LL w;
  28. edge(int _u,int _v,LL _w):u(_u),v(_v),w(_w) {}
  29. };
  30. vector<edge> e;
  31. int dirx[]={,,,-},diry[]={,-,,};
  32. void dij(int n,int m)
  33. {
  34. while(!que.empty())
  35. {
  36. pii p=que.front();
  37. que.pop();
  38. int x=p.fi;
  39. int y=p.se;
  40. LL d=dis[x][y];
  41. if(vis[x][y]) continue;
  42. vis[x][y]=;
  43. for(int i=;i<;i++)
  44. {
  45. int a=x+dirx[i];
  46. int b=y+diry[i];
  47. if(mart[a][b]) continue;
  48. if(!pre[a][b] || dis[a][b]>d+)
  49. {
  50. dis[a][b]=d+;
  51. pre[a][b]=pre[x][y];
  52. que.push(mp(a,b));
  53. }
  54. else if(pre[a][b]!=pre[x][y])
  55. e.pb(edge(pre[a][b],pre[x][y],dis[x][y]+dis[a][b]));
  56. }
  57. }
  58. }
  59. int fa[M],rfa[M];
  60. int rk[M],dep[M];
  61. LL up[M];
  62. bool cmp(edge a,edge b) {return a.w<b.w;}
  63. int Find(int u) { return fa[u]==u?u:fa[u]=Find(fa[u]);}
  64. void Union(int n)
  65. {
  66. sort(e.begin(),e.end(),cmp);
  67. for(int i=;i<=n;i++)
  68. fa[i]=i,rk[i]=;
  69. int sz=e.size();
  70. for(int i=;i<sz;i++)
  71. {
  72. int x=e[i].u;
  73. int y=e[i].v;
  74. LL w=e[i].w;
  75. x=Find(x),y=Find(y);
  76. if(x==y) continue;
  77. if(rk[x]<rk[y]) swap(x,y);
  78. if(rk[x]==rk[y]) rk[x]++;
  79. fa[y]=x,rfa[y]=x,up[y]=w;
  80. }
  81. return ;
  82. }
  83. void dealdep(int u)
  84. {
  85. if(Find(u)==u)
  86. {
  87. dep[u]=;
  88. return ;
  89. }
  90. dealdep(rfa[u]);
  91. dep[u]=dep[rfa[u]]+;
  92. return ;
  93. }
  94. LL solve(int u,int v)
  95. {
  96. LL maxn=;
  97. if(Find(u)!=Find(v)) return -;
  98. if(dep[u]<dep[v]) swap(u,v);
  99. while(dep[u]>dep[v])
  100. {
  101. maxn=max(maxn,up[u]);
  102. u=rfa[u];
  103. }
  104. while(u!=v)
  105. {
  106. maxn=max(maxn,up[u]);
  107. maxn=max(maxn,up[v]);
  108. u=rfa[u],v=rfa[v];
  109. }
  110. return maxn;
  111. }
  112. int main()
  113. {
  114. int n,m,k,q;
  115. scanf("%d%d%d%d",&n,&m,&k,&q);
  116. for(int i=;i<=n;i++)
  117. {
  118. scanf("%s",s+);
  119. for(int j=;j<=m;j++)
  120. if(s[j]=='.') mart[i][j]=;
  121. else mart[i][j]=;
  122. }
  123. for(int i=;i<=m+;i++)
  124. mart[][i]=mart[n+][i]=;
  125. for(int i=;i<=n+;i++)
  126. mart[i][]=mart[i][m+]=;
  127. clr_1(dis);
  128. for(int i=;i<=k;i++)
  129. {
  130. int u,v;
  131. scanf("%d%d",&u,&v);
  132. dis[u][v]=;
  133. pre[u][v]=i;
  134. que.push(mp(u,v));
  135. }
  136. dij(n,m);
  137. Union(k);
  138. for(int i=;i<=k;i++)
  139. if(!dep[i]) dealdep(i);
  140. // for(int i=1;i<=k;i++)
  141. // cout<<"pos:"<<pt[i]/m+1<<" "<<pt[i]%m+1<<" blk:"<<Find(pt[i])/m+1<<" "<<Find(pt[i])%m+1<<" fa:"<<rfa[pt[i]]/m+1<<" "<<rfa[pt[i]]%m+1<<" dep:"<<dep[pt[i]]<<" val:"<<up[pt[i]]<<endl;
  142. while(q--)
  143. {
  144. int u,v;
  145. scanf("%d%d",&u,&v);
  146. printf("%lld\n",solve(u,v));
  147. }
  148. return ;
  149. }

bzoj 4242 水壶 (多源最短路+最小生成树+启发式合并)的更多相关文章

  1. 4144: [AMPPZ2014]Petrol (多源最短路+最小生成树+启发式合并)

    4144: [AMPPZ2014]Petrol Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 752  Solved: 298[Submit][Sta ...

  2. BZOJ 4242: 水壶 Kruskal+BFS

    4242: 水壶 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 427  Solved: 112[Submit][Status][Discuss] D ...

  3. BZOJ 4242 水壶(BFS建图+最小生成树+树上倍增)

    题意 JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有P个,编号为1...P. JOI君只能进入建筑 ...

  4. BZOJ 4242: 水壶(Kruskal重构树 + Bfs)

    题意 一块 \(h ∗ w\) 的区域,存在障碍.空地.\(n\) 个建筑,从一个建筑到另一个建筑的花费为:路径上最长的连续空地的长度. \(q\) 次询问:从建筑 \(s_i\) 到 \(t_i\) ...

  5. BZOJ 1483:[HNOI2009]梦幻布丁(链表+启发式合并)

    [HNOI2009]梦幻布丁 Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一 ...

  6. BZOJ 1483:[HNOI2009]梦幻布丁(链表启发式合并)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1483 题意:中文. 思路:对于每一种颜色,用一个链表串起来,一开始保存一个答案,后面颜色替换的时候再 ...

  7. Bzoj 2733: [HNOI2012]永无乡 数组Splay+启发式合并

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3955  Solved: 2112[Submit][Statu ...

  8. Bzoj 2733: [HNOI2012]永无乡(线段树+启发式合并)

    2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MB Description 永无乡包含 n 座岛,编号从 1 到 n,每座岛都有自己 ...

  9. 【BZOJ4144】[AMPPZ2014]Petrol(最短路+最小生成树+并查集)

    Description 给定一个n个点.m条边的带权无向图,其中有s个点是加油站. 每辆车都有一个油量上限b,即每次行走距离不能超过b,但在加油站可以补满. q次询问,每次给出x,y,b,表示出发点是 ...

随机推荐

  1. AutoCAD DevTV-AUTOCAD二次开发资源合集

    Webcast Language Date AutoCAD .Net - Session 2 English 13-Sep-12 AutoCAD .Net - Session 1 English 6- ...

  2. springCloud全实战超详细代码demo+笔记

    码云: https://gitee.com/houzheng1216/springcloud

  3. laravel 中provider的理解和使用

    https://segmentfault.com/q/1010000004640866

  4. Linux入门(二)Shell基本命令

    上一篇讲了普通用户切换到root用户,今天补充一点,对于Debian和Ubuntu用户,安装时候只有一个普通用户注册,在需要root权限时,我们可以在普通用户模式下输入sudo这个命令运行某些相关特权 ...

  5. 洛谷P3088 挤奶牛

    传送门啦 这个题也是一个单调队列来优化的 $ dp $ ,我们考虑这个题,这个题让我们求出有多少奶牛会觉得拥挤,如果我们还像琪露诺那个题那样单纯用一次单调队列肯定是不行的,因为牛觉不觉得拥挤是受左右的 ...

  6. who am i ?

    Id:Ox9A82 Email:hucvbty@gmail.com 微博:http://weibo.com/1828621423 知乎:Ox9A82 常乐村男子职业技术学院 Syclover拖后腿成员 ...

  7. C#基础之数据类型

    c#有15个预定义类型,其中13个是值类型,两个是引用类型(string 和 object) 1.整型 2.浮点类型 float数据类型用于较小的浮点数,因为它要求的精度较低. double数据类型比 ...

  8. Zabbix监控websphere和weblogic

    本节内容 zabbix java gateway 配置和运行java gateway 配置zabbix server使用java gateway 调整java gateway的日志级别 监控weblo ...

  9. 《精通Python设计模式》学习结构型之代理模式

    这种模式,总会让人想到SRPING中的AOP, 不同语言有不同的实现方式吧. class SensitiveInfo: def __init__(self): self.users = ['nick' ...

  10. CentOS7多实例安装mysq5.6二进制版本

    1丶下载mysql,解压,创建用户,创建软链接 test -d /tools || mkdir /tools ;cd /tools wget http://mirrors.sohu.com/mysql ...