zoukankan      html  css  js  c++  java
  • 4456: [Zjoi2016]旅行者

    4456: [Zjoi2016]旅行者

    https://www.lydsy.com/JudgeOnline/problem.php?id=4456

    分析:

      每次对当前矩阵按长边化一条分治线,然后在对分治线上的点跑最短路,然后可以处理处过分治线的询问。对于不过分治线的,递归处理。

      先写的dijkstra+堆优化,在开O2的情况下可以过,不开O2过不了,卡常~,还是过不了。然后在UOJ的排行榜里(而且UOJ是有大样例的!),看到了两个优化,加上就可以了。

      优化:1、代码41行,用上次的遍历结果初始化。2、将dijkstra改成spfa+SLF优化。

    代码:

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<iostream>
      6 using namespace std;
      7 typedef long long LL;
      8 
      9 char buf[100000],*_p1 = buf,*_p2 = buf;
     10 #define nc() (_p1==_p2&&(_p2=(_p1=buf)+fread(buf,1,100000,stdin),_p1==_p2) ? EOF :*_p1++) 
     11 inline int read() {
     12     int x=0,f=1;char ch=nc();for(;!isdigit(ch);ch=nc())if(ch=='-')f=-1;
     13     for (;isdigit(ch);ch=nc())x=x*10+ch-'0';return x*f;
     14 } 
     15 
     16 #define getid(a,b) ((a - 1) * m + b)
     17 #define pa pair<int,int>
     18 #define mp(a,b) make_pair(a,b)
     19 
     20 const int INF = 1e9;
     21 const int N = 100010;
     22 
     23 struct Que{
     24     int a1,b1,a2,b2,id;
     25 }A[N], B[N];
     26 int dis[N], ans[N], head[N], nxt[N], to[N], len[N];
     27 int n, m, En;
     28 //priority_queue< pa, vector< pa >, greater< pa > > q; // 这才是小根堆!!! 
     29 int q[2000000];
     30 bool vis[N];
     31 
     32 inline void getxy(int id,int &x,int &y) {
     33     x = (id - 1) / m + 1;
     34     y = (id - 1) % m + 1;
     35 }
     36 void dijkstra(int s,int a1,int a2,int b1,int b2,int h) {
     37     int x, y, d = dis[s];
     38     for (int i=a1; i<=a2; ++i) 
     39         for (int j=b1; j<=b2; ++j) {
     40             x = getid(i, j);
     41             dis[x] = h ? dis[x] + d : INF;
     42             vis[x] = false;
     43         }
     44     dis[s] = 0;
     45 /*    q.push(mp(dis[s], s));
     46     while (!q.empty()) {
     47         pa now = q.top(); q.pop();
     48         int u = now.second;
     49         if (vis[u]) continue;
     50         vis[u] = true;
     51         for (int i=head[u]; i; i=nxt[i]) {
     52             int v = to[i];
     53             getxy(v, x, y);
     54             if (x >= a1 && x <= a2 && y >= b1 && y <= b2 && dis[v] > dis[u] + len[i]) {
     55                 dis[v] = dis[u] + len[i];
     56                 q.push(mp(dis[v], v));
     57             }
     58         }
     59     }*/
     60     int L = 100000, R = L - 1;
     61     q[++R] = s;vis[s] = true;
     62     while (L <= R) {
     63         int u = q[L ++];vis[u] = false;
     64         for (int i=head[u]; i; i=nxt[i]) {
     65             int v = to[i];
     66             getxy(v, x, y);
     67             if (x >= a1 && x <= a2 && y >= b1 && y <= b2 && dis[v] > dis[u] + len[i]) {
     68                 dis[v] = dis[u] + len[i];
     69                 if (!vis[v]) {
     70                     if (dis[v] <= dis[q[L]]) q[--L] = v;
     71                     else q[++R] = v;
     72                     vis[v] = true;
     73                 }
     74             }
     75         }
     76     }
     77 }
     78 void solve(int a1,int a2,int b1,int b2,int L,int R) {
     79     if (L > R) return ;
     80     int i, j, k;
     81     if (a2 - a1 > b2 - b1) {
     82         int mid = (a2 + a1) / 2; // a2 + a1
     83         for (i=b1; i<=b2; ++i) {
     84             dijkstra(getid(mid, i), a1, a2, b1, b2, i-b1);
     85             for (j=L; j<=R; ++j) 
     86                 ans[A[j].id] = min(ans[A[j].id], dis[getid(A[j].a1, A[j].b1)] + dis[getid(A[j].a2, A[j].b2)]);
     87         }
     88         i = L - 1, j = R + 1;
     89         for (k=L; k<=R; ++k) {
     90             if (A[k].a1 < mid && A[k].a2 < mid) B[++i] = A[k];
     91             if (A[k].a1 > mid && A[k].a2 > mid) B[--j] = A[k];
     92         }
     93         for (k=L; k<=i; ++k) A[k] = B[k]; solve(a1, mid-1, b1, b2, L, i);
     94         for (k=j; k<=R; ++k) A[k] = B[k]; solve(mid+1, a2, b1, b2, j, R);
     95     }
     96     else {
     97         int mid = (b2 + b1) / 2;
     98         for (i=a1; i<=a2; ++i) {
     99             dijkstra(getid(i, mid), a1, a2, b1, b2, i-a1);
    100             for (j=L; j<=R; ++j) 
    101                 ans[A[j].id] = min(ans[A[j].id], dis[getid(A[j].a1, A[j].b1)] + dis[getid(A[j].a2, A[j].b2)]);
    102         }
    103         i = L - 1, j = R + 1;
    104         for (k=L; k<=R; ++k) {
    105             if (A[k].b1 < mid && A[k].b2 < mid) B[++i] = A[k];
    106             if (A[k].b1 > mid && A[k].b2 > mid) B[--j] = A[k];
    107         }
    108         for (k=L; k<=i; ++k) A[k] = B[k]; solve(a1, a2, b1, mid-1, L, i);
    109         for (k=j; k<=R; ++k) A[k] = B[k]; solve(a1, a2, mid+1, b2, j, R);
    110     }
    111 }
    112 inline void add_edge(int u,int v,int w) {
    113     ++En; to[En] = v; len[En] = w; nxt[En] = head[u]; head[u] = En;
    114     ++En; to[En] = u; len[En] = w; nxt[En] = head[v]; head[v] = En;
    115 }
    116 int main() {
    117     n = read(), m = read();
    118     for (int i=1; i<=n; ++i) {
    119         for (int j=1; j<m; ++j) {
    120             int a = read();
    121             add_edge(getid(i, j), getid(i, j + 1), a);
    122         }
    123     }
    124     for (int i=1; i<n; ++i) {
    125         for (int j=1; j<=m; ++j) {
    126             int a = read();
    127             add_edge(getid(i, j), getid(i + 1, j), a);
    128         }
    129     }
    130     int Case = read();
    131     for (int a,b,i=1; i<=Case; ++i) {
    132         A[i].a1 = read(), A[i].b1 = read(); 
    133         A[i].a2 = read(), A[i].b2 = read(); 
    134         A[i].id = i; ans[i] = INF;
    135     }
    136     solve(1, n, 1, m, 1, Case);
    137     for (int i=1; i<=Case; ++i) printf("%d
    ",ans[i]);
    138     return 0;
    139 }
  • 相关阅读:
    统一建模语言UML轻松入门之综合实例
    统一建模语言UML轻松入门之动态建模
    LINQ体验(3)——C# 3.0新语言特性和改进(下篇) 【转】
    Visual Studio 2008新特性【转】
    vs2008 新特性【转】
    LINQ体验(1)——C# 3.0新语言特性和改进(上篇) 【转】
    C# 3.0 的Lambda表达式(Lambda Expressions)【转】
    LINQ体验(2)——C# 3.0新语言特性和改进(上篇) 【转】
    结构体计算结构体字节大小以及字节对齐
    web.config 中SessionState的配置
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9609293.html
Copyright © 2011-2022 走看看