• 小雨坐地铁【分层图】【最短路】


     

    思路

      如果考虑暴力建图的方法

      对于每一条线路的每一个站点可到达的站点建边

      在每条线路有1e5个站点的条件下显然是不现实的

      如何解决建图的问题是此题的关键

      因为有转车和车费逐步增加的情况存在

      很容易想到分层图的概念

      通过把路线看作不同的图层

      就能把转车的概念转化为层与层之间的转化概念

      令图层层数为 0 ~ m

      其中第 m 层为中转线

      所有的转车行为必须先转入中转层,再改换到其他的路线层

      显然,去中转线的费用应为a[i],由中转层上其他车的费用为0

      之后对于每一层的路线只要正常建图即可

    CODE

      1 #include <bits/stdc++.h>
      2 #define dbg(x) cout << #x << "=" << x << endl
      3 #define eps 1e-8
      4 #define pi acos(-1.0)
      5 
      6 using namespace std;
      7 typedef long long LL;
      8 
      9 template<class T>inline void read(T &res)
     10 {
     11     char c;T flag=1;
     12     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
     13     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
     14 }
     15 
     16 namespace _buff {
     17     const size_t BUFF = 1 << 19;
     18     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
     19     char getc() {
     20         if (ib == ie) {
     21             ib = ibuf;
     22             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
     23         }
     24         return ib == ie ? -1 : *ib++;
     25     }
     26 }
     27 
     28 int qread() {
     29     using namespace _buff;
     30     int ret = 0;
     31     bool pos = true;
     32     char c = getc();
     33     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
     34         assert(~c);
     35     }
     36     if (c == '-') {
     37         pos = false;
     38         c = getc();
     39     }
     40     for (; c >= '0' && c <= '9'; c = getc()) {
     41         ret = (ret << 3) + (ret << 1) + (c ^ 48);
     42     }
     43     return pos ? ret : -ret;
     44 }
     45 
     46 const int maxn = 2e6 + 7;
     47 const int inf  = 0x3f3f3f3f;
     48 
     49 int head[maxn << 1], edge[maxn << 1], w[maxn << 1], nxt[maxn << 1];
     50 int cnt;
     51 
     52 inline void BuildGraph (int u, int v, int c) {
     53     cnt++;
     54     edge[cnt] = v;
     55     nxt[cnt]  = head[u];
     56     w[cnt] = c;
     57     head[u] = cnt;
     58 }
     59 
     60 struct node {
     61     int u,v;
     62     bool operator <(const node &t) const {
     63         return u > t.u;
     64     }
     65 };
     66 
     67 int n,m,s,t,k;
     68 int dis[maxn << 1];
     69 bool vis[maxn << 1];
     70 
     71 priority_queue<node> q;
     72 
     73 void dijkstra(int s) {
     74     memset(dis, 0x3f, sizeof(dis));
     75     dis[s] = 0;
     76     node temp;
     77     temp.u = 0;
     78     temp.v = s;
     79     q.push(temp);
     80     while(!q.empty()) {
     81         int u = q.top().v;
     82         int d = q.top().u;
     83         q.pop();
     84         if(vis[u]) continue;
     85         vis[u] = true;
     86         for (int i = head[u]; i; i = nxt[i]) {
     87             int v = edge[i];
     88             int c = w[i];
     89             if(dis[v] > dis[u] + c && !vis[v]) {
     90                 dis[v] = dis[u] + c;
     91                 node p;
     92                 p.u = dis[v], p.v = v;
     93                 q.push(p);
     94             }
     95         }
     96     }
     97 }
     98 
     99 int a[maxn << 1], b[maxn << 1], c[maxn << 1];
    100 
    101 int main()
    102 {
    103     read(n); read(m); read(s); read(t);
    104     for ( int i = 1; i <= m; ++i ) {
    105         read(a[i]); read(b[i]); read(c[i]);
    106         int u = 0, v = -1;
    107         for ( int j = 1; j <= c[i]; ++j ) {
    108             read(u);
    109             if(~v) {
    110                 BuildGraph((i - 1) * n + u, (i - 1) * n + v, b[i]);
    111                 BuildGraph((i - 1) * n + v, (i - 1) * n + u, b[i]);
    112             }
    113             v = u;
    114             BuildGraph((i - 1) * n + u, n * m + u, 0);
    115             BuildGraph((n * m) + u, (i - 1) * n + u, a[i]);
    116         }
    117     }
    118     dijkstra(n * m + s);
    119     int ans = INT_MAX;
    120     for ( int i = 1; i <= m; ++i ) {
    121         ans = min(ans, dis[n * i + t]);
    122     }
    123     if(ans == inf) {
    124         puts("-1");
    125         return 0;
    126     }
    127     cout << ans << endl;
    128     return 0;
    129 }
    View Code
  • 相关阅读:
    注册tomcat为服务
    BootStrap
    Passive DNS
    一个插件平台
    HDU 4394 BFS
    设计模式--组合模式--商品排序案例
    Windows平台编译openssl-0.9.8k库(32位、64位)
    JavaScript之this释疑
    OpenLayers3基础教程——OL3 介绍control
    我的Android进阶之旅------&gt; Android为TextView组件中显示的文本加入背景色
  • 原文地址:https://www.cnblogs.com/orangeko/p/12850336.html
Copyright © 2020-2023  润新知