zoukankan      html  css  js  c++  java
  • 小雨坐地铁【分层图】【最短路】

     

    思路

      如果考虑暴力建图的方法

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

      在每条线路有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
  • 相关阅读:
    CodeForces 681D Gifts by the List (树上DFS)
    UVa 12342 Tax Calculator (水题,纳税)
    CodeForces 681C Heap Operations (模拟题,优先队列)
    CodeForces 682C Alyona and the Tree (树上DFS)
    CodeForces 682B Alyona and Mex (题意水题)
    CodeForces 682A Alyona and Numbers (水题,数学)
    Virtualizing memory type
    页面跳转
    PHP Misc. 函数
    PHP 5 Math 函数
  • 原文地址:https://www.cnblogs.com/orangeko/p/12850336.html
Copyright © 2011-2022 走看看