zoukankan      html  css  js  c++  java
  • BZOJ 2125: 最短路

    2125: 最短路

    Time Limit: 1 Sec  Memory Limit: 259 MB
    Submit: 756  Solved: 331
    [Submit][Status][Discuss]

    Description

    给一个N个点M条边的连通无向图,满足每条边最多属于一个环,有Q组询问,每次询问两点之间的最短路径。

    Input

    输入的第一行包含三个整数,分别表示N和M和Q 下接M行,每行三个整数v,u,w表示一条无向边v-u,长度为w 最后Q行,每行两个整数v,u表示一组询问

    Output

    输出Q行,每行一个整数表示询问的答案

    Sample Input

    9 10 2
    1 2 1
    1 4 1
    3 4 1
    2 3 1
    3 7 1
    7 8 2
    7 9 2
    1 5 3
    1 6 4
    5 6 1
    1 9
    5 7

    Sample Output

    5
    6

    HINT

    对于100%的数据,N<=10000,Q<=10000

    Source

     
    [Submit][Status][Discuss]
      1 #include <cstdio>
      2 #include <cstring>
      3 
      4 inline int nextChar(void)
      5 {
      6     static const int siz = 1 << 20;
      7     
      8     static char buf[siz];
      9     static char *hd = buf + siz;
     10     static char *tl = buf + siz;
     11     
     12     if (hd == tl)
     13         fread(hd = buf, 1, siz, stdin);
     14         
     15     return int(*hd++);
     16 }
     17 
     18 inline int nextInt(void)
     19 {
     20     int r = 0, c = nextChar();
     21     
     22     for (; c < 48; c = nextChar());
     23     for (; c > 47; c = nextChar())
     24         r = r * 10 + c - '0';
     25     
     26     return r;
     27 }
     28 
     29 template <class T>
     30 inline T min(const T &a, const T &b)
     31 {
     32     return a < b ? a : b;
     33 }
     34 
     35 template <class T>
     36 inline T abs(const T &x)
     37 {
     38     return x < 0 ? -x : x;
     39 }
     40 
     41 const int mxn = 500005;
     42 const int inf = 0x3f3f3f3f;
     43 
     44 int n, m, q;
     45 
     46 int tot;
     47 int hd[mxn];
     48 int to[mxn];
     49 int vl[mxn];
     50 int nt[mxn];
     51 
     52 inline void add(int x, int y, int w)
     53 {
     54     nt[tot] = hd[x];
     55     to[tot] = y;
     56     vl[tot] = w;
     57     hd[x] = tot++;
     58 }
     59 
     60 int dis[mxn];
     61 int que[mxn];
     62 int vis[mxn];
     63 
     64 inline void spfa(void)
     65 {
     66     memset(vis,   0, sizeof vis);
     67     memset(dis, inf, sizeof dis);
     68     
     69     int lt = 0, rt = 0;
     70     
     71     que[rt++] = 1;
     72     vis[1] = 1;
     73     dis[1] = 0;
     74     
     75     while (lt != rt)
     76     {
     77         int u = que[lt++], v;
     78 
     79         if (lt > mxn)lt = 0;
     80         
     81         vis[u] = 0;
     82         
     83         for (int i = hd[u]; ~i; i = nt[i])
     84             if (v = to[i], dis[v] > dis[u] + vl[i])
     85             {
     86                 dis[v] = dis[u] + vl[i];
     87                 
     88                 if (!vis[v])
     89                 {
     90                     vis[que[rt++] = v] = 1;
     91 
     92                     if (rt > mxn)rt = 0;
     93                 }
     94             }
     95     }
     96 }
     97 
     98 struct data
     99 {
    100     int u, v, w;
    101     
    102     inline data(void) {};
    103     inline data(int a, int b, int c)
    104         : u(a), v(b), w(c) {};
    105 }stk[mxn]; int top;
    106 
    107 int tim;
    108 int dfn[mxn];
    109 int low[mxn];
    110 
    111 int cnt;
    112 int cir[mxn];
    113 int len[mxn];
    114 int bel[mxn];
    115 int fat[mxn][25];
    116 
    117 inline void addcir(int u, int v)
    118 {
    119     ++cnt;
    120     
    121     while (u != stk[top].u && v != stk[top].v)
    122     {
    123         int x = stk[top].u, y = stk[top].v, w = stk[top].w;
    124         
    125         if (x != u)bel[x] = cnt, fat[x][0] = u;
    126         if (y != u)bel[y] = cnt, fat[y][0] = u;
    127         
    128         len[cnt] += w, cir[x] = cir[y] + w;
    129         
    130         --top;
    131     }
    132     
    133     {
    134         int x = stk[top].u, y = stk[top].v, w = stk[top].w;
    135         
    136         len[cnt] += w, cir[x] = cir[y] + w;
    137         
    138         fat[y][0] = x;
    139         
    140         --top;
    141     }
    142 }
    143 
    144 void tarjan(int u, int f)
    145 {
    146     dfn[u] = low[u] = ++tim;
    147     
    148     for (int i = hd[u], v; ~i; i = nt[i])
    149         if ((v = to[i]) != f)
    150         {
    151             if (!dfn[v])
    152             {
    153                 stk[++top] = data(u, v, vl[i]), tarjan(v, u);
    154                 
    155                 if (low[v] < low[u])low[u] = low[v];
    156                 
    157                 if (low[v] >= dfn[u])addcir(u, v);
    158             }
    159             else if (dfn[v] < low[u])
    160                 low[u] = dfn[v], stk[++top] = data(u, v, vl[i]);    
    161         }
    162 }
    163 
    164 int dep[mxn];
    165 
    166 void build(int u)
    167 {
    168     for (int i = hd[u]; ~i; i = nt[i])
    169         dep[to[i]] = dep[u] + 1, build(to[i]);
    170 }
    171 
    172 inline void prework(void)
    173 {
    174     spfa();
    175     
    176     tarjan(1, 0);
    177     
    178     for (int i = 1; i <= 20; ++i)
    179         for (int j = 1; j <= n; ++j)
    180             fat[j][i] = fat[fat[j][i - 1]][i - 1];
    181     
    182     memset(hd, -1, sizeof hd), tot = 0;
    183     
    184     for (int i = 2; i <= n; ++i)
    185         add(fat[i][0], i, 0);
    186     
    187     dep[1] = 1, build(1);
    188 }
    189 
    190 inline int getLCA(int a, int b, int &x, int &y)
    191 {
    192     if (dep[a] < dep[b])
    193         a ^= b ^= a ^= b;
    194     
    195     int ret = dis[a] + dis[b];
    196     
    197     for (int i = 20; ~i; --i)
    198         if (dep[fat[a][i]] >= dep[b])
    199             a = fat[a][i];
    200     
    201     if (a == b)
    202         return x = y = a, ret - dis[a] * 2;
    203     
    204     for (int i = 20; ~i; --i)
    205         if (fat[a][i] != fat[b][i])
    206             a = fat[a][i],
    207             b = fat[b][i];
    208     
    209     return x = a, y = b, ret - dis[fat[a][0]] * 2;
    210 }
    211 
    212 signed main(void)
    213 {
    214     n = nextInt();
    215     m = nextInt();
    216     q = nextInt();
    217     
    218     memset(hd, -1, sizeof(hd)), tot = 0;
    219     
    220     for (int i = 1; i <= m; ++i)
    221     {
    222         int x = nextInt();
    223         int y = nextInt();
    224         int w = nextInt();
    225         
    226         add(x, y, w);
    227         add(y, x, w);
    228     }
    229     
    230     prework();
    231     
    232     for (int i = 1, x, y; i <= q; ++i)
    233     {
    234         int a = nextInt();
    235         int b = nextInt();
    236         
    237         int ans = getLCA(a, b, x, y);
    238         
    239         if (bel[x] && bel[x] == bel[y])
    240         {
    241             ans = dis[a] + dis[b] - dis[x] - dis[y];
    242             
    243             int len1 = abs(cir[x] - cir[y]);
    244             int len2 = len[bel[x]] - len1;
    245             
    246             ans += min(len1, len2);
    247         }
    248         
    249         printf("%d
    ", ans);
    250     }
    251 }

    @Author: YouSiki

  • 相关阅读:
    C语言面试题分类->宏定义
    c语言位运算
    C语言一个程序的存储空间
    收藏的链接-English
    侧滑关闭Activity的解决方案——SwipeBackLayout
    实现ViewPager的联动效果
    由Toolbar造成的ListView最后一项显示不全
    收藏的链接-Stub
    收藏的链接-Git
    收藏的链接
  • 原文地址:https://www.cnblogs.com/yousiki/p/6442107.html
Copyright © 2011-2022 走看看