记录编号 411041 评测结果 AAAAAA
题目名称 [BJOI2006] 狼抓兔子 最终得分 100
用户昵称 GravatarkZime 是否通过 通过
代码语言 C++ 运行时间 0.277 s
提交时间 2017-06-03 16:14:11 内存使用 78.81 MiB
显示代码纯文本
  1. # include <bits/stdc++.h>
  2. # define INF 0x7fffffff
  3. # define MAXN 2001000
  4. using namespace std;
  5.  
  6. char buf[1 << 18], *fs, *ft;
  7. inline char getc() {
  8. return (fs == ft && (ft = (fs = buf) + fread(buf, 1, 1 << 18, stdin)), fs == ft) ? EOF : *fs++;
  9. }
  10.  
  11. inline int gn() {
  12. int k = 0, f = 1;
  13. char c = getc();
  14. for(; !isdigit(c); c = getc()) if(c == '-') f = -1;
  15. for(; isdigit(c); c = getc()) k = k * 10 + c - '0';
  16. return k * f;
  17. }
  18.  
  19. struct edge {
  20. int to, w;
  21. edge *ne;
  22. inline edge() {
  23. to = 0, w = 0, ne = NULL;
  24. }
  25. inline edge(int to_, int w_, edge *ne_) {
  26. to = to_;
  27. w = w_;
  28. ne = ne_;
  29. }
  30. }*head[MAXN];
  31.  
  32. inline void addedge(int fr, int to, int w) {
  33. head[fr] = new edge(to, w, head[fr]);
  34. head[to] = new edge(fr, w, head[to]);
  35. }
  36.  
  37. int n, m, ans, S, T, dis[MAXN], q[MAXN << 3];
  38. bool inq[MAXN];
  39.  
  40. void build(){
  41. S=0,T=((n-1)*(m-1))<<1|1;
  42. for (int i=1; i<=n; i++)
  43. for (int j=1; j<m; j++){
  44. int x=gn(),u,v;
  45. if (i==1) u=S,v=j;
  46. else if (i==n) u=((i-2)<<1|1)*(m-1)+j,v=T;
  47. else u=((i-2)<<1|1)*(m-1)+j,v=((i-1)<<1)*(m-1)+j;
  48. addedge(u, v, x);
  49. }
  50. for (int i=1; i<n; i++)
  51. for (int j=1; j<=m; j++){
  52. int x=gn(),u,v;
  53. if (j==1) u=((i-1)<<1|1)*(m-1)+1,v=T;
  54. else if (j==m) u=S,v=((i-1)<<1|1)*(m-1);
  55. else u=((i-1)<<1)*(m-1)+j-1,v=((i-1)<<1|1)*(m-1)+j;
  56. addedge(u, v, x);
  57. }
  58. for (int i=1; i<n; i++)
  59. for (int j=1; j<m; j++){
  60. int x=gn(),u,v;
  61. u=((i-1)<<1)*(m-1)+j,v=((i-1)<<1|1)*(m-1)+j;
  62. addedge(u, v, x);
  63. }
  64. }
  65.  
  66. inline int spfa() {
  67. int l = 1, r = 1;
  68. memset(dis, 42, sizeof(dis));
  69. dis[S] = 0;
  70. inq[S] = 1;
  71. q[1] = S;
  72. while(l <= r) {
  73. int u = q[l++];
  74. inq[u] = 0;
  75. for(edge *e = head[u]; e; e = e->ne) {
  76. if(dis[e->to] > dis[u] + e->w) {
  77. dis[e->to] = dis[u] + e->w;
  78. if(!inq[e->to]) inq[e->to] = 1, q[++r] = e->to;
  79. }
  80. }
  81. }
  82. return dis[T];
  83. }
  84.  
  85. inline void solve() {
  86. if(n == 1 || m == 1) {
  87. if(n > m) swap(n, m);
  88. ans = INF;
  89. for(int i = 1; i < m; i++) ans = min(gn(), ans);
  90. if(ans == INF) ans = 0;
  91. printf("%d\n", ans);
  92. } else {
  93. build();
  94. printf("%d\n", spfa());
  95. }
  96. }
  97.  
  98. int main() {
  99. # ifdef LOCAL
  100. freopen("in", "r", stdin);
  101. # else
  102. freopen("bjrabbit.in", "r", stdin);
  103. freopen("bjrabbit.out", "w", stdout);
  104. # endif
  105. n = gn();
  106. m = gn();
  107. solve();
  108. return 0;
  109. }