zoukankan      html  css  js  c++  java
  • bzoj2834 回家的路

     题目描述

    初步思路

       一眼最短路,然后有换乘这种操作,自然想到分层之后连边,每层图中的边,边权为2,层与层之间的边边权为1就好啦?   但是所有的正解都把我否了?! 丝毫不知道错哪儿,可能是题干看错了?   最后惊讶的发现...看错题了(555......)

    题目正解

      也是分层图最短路,不过怎么建图时重点。 分横向,纵向两个方向考虑。然后将同行或者同列的节点连边,跑最短路即可。 另外此题有特判情况,如果起点或者重点与换乘站重合,此时横着竖着都需要判,不能只判断一个方向。

    代码

      1 #include <queue>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 using namespace std;
      6 const int M = 100020;
      7 #define ll long long
      8 #define Min(a, b) ((a) < (b) ? (a) : (b))
      9 #define Max(a, b) ((a) > (b) ? (a) : (b))
     10 int n, m, cnt;
     11 struct node
     12 {
     13     int x, y, idx;
     14     void Read(int p)
     15     {
     16         scanf("%d%d", &x, &y);
     17         idx = p;
     18     }
     19 }a[M];
     20 int head[M], to[M * 10], nex[M * 10], val[M * 10];
     21 bool inq[M][2];
     22 ll f[M * 10], dis[M * 10][2];
     23 deque <pair <int , int > > q;
     24 void addedge(int a, int b, int v)
     25 {
     26     nex[++ cnt] = head[a];
     27     head[a] = cnt;
     28     to[cnt] = b;
     29     f[cnt] = v;
     30 }
     31 bool cmp1(const node &x, const node &y)
     32 {
     33     return x.x == y.x ? x.y < y.y : x.x < y.x;
     34 }
     35 bool cmp2(const node &x, const node &y)
     36 {
     37     return x.y == y.y ? x.x < y.x : x.y < y.y;
     38 }
     39 bool cmp3(const node &x, const node &y)
     40 {
     41     return x.idx < y.idx;
     42 }
     43 pair <int, int > u;
     44 void spfa()
     45 {
     46     while(!q.empty())
     47     {
     48         u = q.front();
     49         q.pop_front();
     50         int tx = u.first;
     51         int p = u.second;
     52         inq[tx][p] = 0;
     53         for(int i = head[tx] ; i ; i = nex[i])
     54         {
     55             int v = to[i];
     56             if(!p && a[tx].x == a[v].x || p && a[tx].y == a[v].y)
     57                 if(dis[v][p] > dis[tx][p] + f[i])
     58                 {
     59                     dis[v][p] = dis[tx][p] + f[i];
     60                     if(!inq[v][p])
     61                     {
     62                         inq[v][p] = 1;
     63                         pair <int, int > tmp;
     64                         tmp = q.front();
     65                         if(q.empty() || dis[tmp.first][p] >= dis[to[i]][p] - 1930) 
     66                                 q.push_front(make_pair(v , p));
     67                         else
     68                             q.push_back(make_pair(v, p));
     69                     }
     70                 }
     71             if(p && a[tx].x == a[v].x || !p && a[tx].y == a[v].y)
     72                 if(dis[v][p ^ 1] > dis[tx][p] + f[i] + 1)
     73                 {
     74                     dis[v][p ^ 1] = dis[tx][p] + f[i] + 1;
     75                     if(!inq[v][p ^ 1])
     76                     {
     77                         inq[v][p ^ 1] = 1;
     78                         pair <int, int > tmp;
     79                         tmp = q.front();
     80                         if(q.empty() || dis[tmp.first][p] >= dis[to[i]][p] - 1930) 
     81                                 q.push_front(make_pair(v , p ^ 1));
     82                         else
     83                             q.push_back(make_pair(v, p ^ 1));
     84                     }
     85                 }
     86         }
     87     }
     88 }
     89 int main()
     90 {
     91     //freopen("2834.in", "r", stdin);
     92     //freopen("2834.out", "w", stdout);
     93     scanf("%d%d", &n, &m);
     94     for(int i = 1 ; i <= m ; i ++)
     95         a[i].Read(i);
     96     a[0].Read(0);
     97     a[m + 1].Read(m + 1);
     98     sort(a, a + m + 2, cmp1);
     99     for(int i = 0 ; i <= m ; i ++)
    100         if(a[i].x == a[i + 1].x)
    101         {
    102             int tre = 2 * (a[i + 1].y - a[i].y);
    103             addedge(a[i].idx, a[i + 1].idx, tre);
    104             addedge(a[i + 1].idx, a[i].idx, tre);
    105         }
    106     sort(a, a + m + 2, cmp2);
    107     for(int i = 0 ; i <= m ; i ++)
    108         if(a[i].y == a[i + 1].y)
    109         {
    110             int tre = 2 * (a[i + 1].x - a[i].x);
    111             addedge(a[i].idx, a[i + 1].idx, tre);
    112             addedge(a[i + 1].idx, a[i].idx, tre);
    113         }
    114     sort(a, a + m + 2, cmp3);
    115     memset(dis, 0x3f, sizeof dis);
    116     dis[0][0] = dis[0][1] = 0;
    117     inq[0][0] = inq[0][1] = 1; 
    118     q.push_front(make_pair(0, 0));
    119     q.push_back(make_pair(0, 1));
    120     spfa();
    121     if(Min(dis[m + 1][0], dis[m + 1][1]) == 0x3f3f3f3f3f3f3f3fll)
    122         printf("-1");
    123     else
    124         printf("%lld
    " , Min(dis[m + 1][0] , dis[m + 1][1]));
    125     return 0;
    126 }
    View Code

    忽略那个双端队列。 因为我之前数组开小导致TLE,我还以为是spfa的锅...... 结果调完之后,发现加上优化比不加都慢.....

    总结

      555....调了一下午。 思路WA了一发,代码WA了一波.....  不过题是好题(QAQ)

  • 相关阅读:
    Word转pdf
    jquery 中json数组的操作 增删改
    Js、Jquery定时执行(一次或者重复多次,取消重复)
    sql server 2008 (不允许保存更改,您所做的更改要求删除并重新创建以下表) 的解决办法
    C#中 ArrayList 的使用
    Jquery正则表达式公式
    C#判断字符串是否存在字母及字符串中字符的替换实例
    纳闷的EF异常:在提供程序连接上启动事务时出错
    C# WinForm获取当前路径汇总
    Entity Framwork 6 编译出错的问题(VS2012)
  • 原文地址:https://www.cnblogs.com/0724-zcsblog/p/11527970.html
Copyright © 2011-2022 走看看