• BZOJ_4152


    巧妙的性质:一个点最多只会与他横纵坐标最近的那4个点连边。所以我们sort sort连边建图。跑dijkstra

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <vector>
     4 #include <queue>
     5 #include <algorithm>
     6 #include <cmath>
     7 #include <iostream>
     8 using namespace std;
     9 const int maxn = 200003;
    10 int n;
    11 int first[maxn],to[maxn*8],next[maxn*8],dis[maxn*8],eg;
    12 inline void addedge(int x,int y,int d) {
    13     next[++eg] = first[x];first[x] = eg;
    14     to[eg] = y;dis[eg] = d;
    15 }
    16 inline void add(int x,int y,int d) {
    17     addedge(x,y,d);
    18     addedge(y,x,d);
    19 }
    20 struct Point {
    21     int x,y,key;
    22     void read() {
    23         scanf("%d%d",&x,&y);
    24     }
    25 }dian[maxn];
    26 bool cmp1(const Point& p,const Point& q) {
    27     return p.x < q.x;
    28 }
    29 bool cmp2(const Point& p,const Point& q) {
    30     return p.y < q.y;
    31 }
    32 struct rp {
    33     int v,key;
    34     rp(int _v = 0,int _key = 0) {
    35         v = _v;key = _key;
    36     }
    37 };
    38 struct cmp {
    39     bool operator()(const rp& a,const rp& b) {
    40         return a.v > b.v;
    41     }
    42 };
    43 priority_queue<rp,vector<rp>,cmp>dui;
    44 int dist[maxn];
    45 bool vis[maxn];
    46 inline void dijkstra(int u) {
    47     memset(dist,0x3f,sizeof(dist));
    48     dist[u] = 0;
    49     rp a = rp(0,1);
    50     dui.push(a);
    51     while(!vis[n]) {
    52         rp zxr_handsome = dui.top();
    53         dui.pop();
    54         if(vis[zxr_handsome.key]) continue;
    55         vis[zxr_handsome.key] = 1;
    56         for(int i = first[zxr_handsome.key];i;i = next[i]) {
    57             int v = to[i];
    58             int newdist = dist[zxr_handsome.key] + dis[i];
    59             if(newdist < dist[v]) {
    60                 dist[v] = newdist;
    61                 dui.push(rp(newdist,v));
    62             }
    63         }
    64     }
    65     cout << dist[n] << endl;
    66 }
    67 int main() {
    68     scanf("%d",&n);
    69     for(int i = 1 ; i <= n ; ++i) dian[i].read(),dian[i].key = i;
    70     sort(dian+1,dian+1+n,cmp1);
    71     /*for(int i = 1 ; i <= n ; ++i) {
    72         printf("%d ",dian[i].x);
    73     }
    74     cout << endl << endl;*/
    75     for(int i = 2 ; i <= n ; ++i)
    76         add(dian[i].key,dian[i-1].key,dian[i].x - dian[i-1].x);
    77     sort(dian+1,dian+1+n,cmp2);
    78     for(int i = 2 ; i <= n ; ++i)
    79         add(dian[i].key,dian[i-1].key,dian[i].y - dian[i-1].y);
    80     dijkstra(1);
    81 }
    View Code

    然后据说这道题SPFA过不了,,我就过了一发。。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <vector>
     4 #include <queue>
     5 #include <algorithm>
     6 #include <cmath>
     7 #include <iostream>
     8 using namespace std;
     9 const int maxn = 200003;
    10 int n;
    11 int first[maxn],to[maxn*8],next[maxn*8],dis[maxn*8],eg;
    12 inline void addedge(int x,int y,int d) {
    13     next[++eg] = first[x];first[x] = eg;
    14     to[eg] = y;dis[eg] = d;
    15 }
    16 inline void add(int x,int y,int d) {
    17     addedge(x,y,d);
    18     addedge(y,x,d);
    19 }
    20 struct Point {
    21     int x,y,key;
    22     void read() {
    23         scanf("%d%d",&x,&y);
    24     }
    25 }dian[maxn];
    26 bool cmp1(const Point& p,const Point& q) {
    27     return p.x < q.x;
    28 }
    29 bool cmp2(const Point& p,const Point& q) {
    30     return p.y < q.y;
    31 }
    32 int dist[maxn];
    33 bool ins[maxn];
    34 inline void spfa(int u) {
    35     deque<int>Q;
    36     Q.push_front(u);
    37     memset(dist,0x3f,sizeof(dist));
    38     dist[u] = 0;
    39     while(!Q.empty()) {
    40         int u = Q.front();
    41         Q.pop_front();
    42         ins[u] = false;
    43         for(int i = first[u];i;i = next[i]) {
    44             int v = to[i];
    45             int newdist = dist[u] + dis[i];
    46             if(newdist < dist[v]) {
    47                 dist[v] = newdist;
    48                 if(!ins[v]) {
    49                     if(Q.empty()) {
    50                         Q.push_front(v);
    51                     } else {
    52                         int top = Q.front();
    53                         if(dist[top] < dist[v]) Q.push_back(v);
    54                         else Q.push_front(v);
    55                     }
    56                     ins[v] = 1;
    57                 }
    58             }
    59         }
    60     }
    61     cout << dist[n];
    62 }
    63 int main() {
    64     scanf("%d",&n);
    65     for(int i = 1 ; i <= n ; ++i) dian[i].read(),dian[i].key = i;
    66     sort(dian+1,dian+1+n,cmp1);
    67     for(int i = 2 ; i <= n ; ++i)
    68         add(dian[i].key,dian[i-1].key,dian[i].x - dian[i-1].x);
    69     sort(dian+1,dian+1+n,cmp2);
    70     for(int i = 2 ; i <= n ; ++i)
    71         add(dian[i].key,dian[i-1].key,dian[i].y - dian[i-1].y);
    72     spfa(1);
    73 }
    View Code

    所以说双端队列就是好用。

  • 相关阅读:
    1015词法分析
    0909作业
    华为云专家来公司
    SVN与Git的优点差异比较
    eclipse快捷键大全
    Servlet,HttpServletRequest 和 HttpServletResponse
    XML
    JDBC
    XMIND快捷键
    java数据
  • 原文地址:https://www.cnblogs.com/registerzxr/p/5081880.html
Copyright © 2020-2023  润新知