• HDU Traffic Real Time Query System


    题目大意是:对于(n, m)的图,给定边a, b查询从a到b要经过的割点的最少数目。

    先tarjan算法求双连通然后缩点,即对于每个割点将周围的每个双连通看成一个点与之相连。然后求解LCA即可,距离dis[u]表示从根出发到u的遍历过程中经过的割顶的数目,利用

    tarjan离线算法, 最后答案是:dis[u] + dis[v] - 2*dis[findset(v)] + (findset(v) > bcc_cnt)。注意findset(v) > bcc_cnt表示当LCA(u,v) 为割顶时的判断,此时必须加1。

    代码:

      1 #include <iostream>
      2 #include <sstream>
      3 #include <cstdio>
      4 #include <climits>
      5 #include <cstring>
      6 #include <cstdlib>
      7 #include <string>
      8 #include <stack>
      9 #include <map>
     10 #include <cmath>
     11 #include <vector>
     12 #include <queue>
     13 #include <algorithm>
     14 #define esp 1e-6
     15 #define pi acos(-1.0)
     16 #define pb push_back
     17 #define lson l, m, rt<<1
     18 #define rson m+1, r, rt<<1|1
     19 #define mp(a, b) make_pair((a), (b))
     20 #define in  freopen("in.txt", "r", stdin);
     21 #define out freopen("out.txt", "w", stdout);
     22 #define print(a) printf("%d
    ",(a));
     23 #define bug puts("********))))))");
     24 #define stop  system("pause");
     25 #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
     26 #define inf 0x0f0f0f0f
     27 
     28 using namespace std;
     29 typedef long long  LL;
     30 typedef vector<int> VI;
     31 typedef pair<int, int> pii;
     32 typedef vector<pii> VII;
     33 typedef vector<pii, int> VIII;
     34 typedef VI:: iterator IT;
     35 #define eid first
     36 #define vtx second
     37 
     38 const int maxn = 10000 + 10000;
     39 const int maxm = 100000 + 10000;
     40 int pre[maxn], low[maxn], bccno[maxn], ebccno[maxm], iscut[maxn], vis[maxm], ans[maxn], pa[maxn], bcc_cnt, dfs_clock;
     41 VI g[maxn], bcc[maxn];
     42 VII adj[maxn], query[maxn];
     43 struct edge{
     44 int u, v;
     45 } ee[maxm];
     46 stack<int> S;
     47 
     48 int dfs(int u, int fa)
     49 {
     50     int lowu = pre[u] = ++dfs_clock;
     51     int child = 0;
     52     for(int i = 0; i < adj[u].size(); i++)
     53         {
     54             int v = adj[u][i].vtx;
     55             if(!pre[v])
     56             {
     57                 S.push(adj[u][i].eid);
     58                 child++;
     59                 vis[adj[u][i].eid] = 1;
     60                 int lowv = dfs(v, u);
     61                 lowu = min(lowu, lowv);
     62                 if(lowv >= pre[u])
     63                 {
     64                     iscut[u] = 1;
     65                     bcc_cnt++;
     66                     bcc[bcc_cnt].clear();
     67                     for(;;)
     68                     {
     69                         int e = S.top(); S.pop();
     70                         bcc[bcc_cnt].pb(e);
     71                         ebccno[e] = bcc_cnt;
     72                         bccno[ee[e].u] = bccno[ee[e].v] = bcc_cnt;
     73                         if(e == adj[u][i].eid)  break;
     74                     }
     75                 }
     76             }
     77             else if(pre[v] < pre[u])
     78             {
     79                   if(v != fa)
     80                   {
     81                      lowu = min(lowu, pre[v]);
     82                      S.push(adj[u][i].eid);
     83                      vis[adj[u][i].eid] = 1;
     84                   }
     85                   else {
     86                     if( !vis[adj[u][i].eid])
     87                     {
     88                       lowu = min(lowu, pre[v]);
     89                       S.push(adj[u][i].eid);
     90                       vis[adj[u][i].eid] = 1;
     91                     }
     92                   }
     93             }
     94         }
     95         if(fa < 0 && child == 1)
     96         {
     97             iscut[u] = 0;
     98         }
     99         return low[u] = lowu;
    100 }
    101 void find_bcc(int n)
    102 {
    103     memset(pre, 0, sizeof(pre));
    104     memset(bccno, 0, sizeof(bccno));
    105     memset(iscut, 0, sizeof(iscut));
    106     memset(ebccno, 0, sizeof(ebccno));
    107     memset(vis, 0, sizeof(vis));
    108 
    109     while(!S.empty()) S.pop();
    110     dfs_clock = bcc_cnt = 0;
    111     for(int i = 0; i < n ;i++)
    112         if(!pre[i])
    113         dfs(i, -1);
    114 }
    115 int flag[maxn];
    116 int dis[maxn];
    117 int vv[maxn];
    118 int findset(int x)
    119 {
    120     return pa[x] == x ? x : pa[x] = findset(pa[x]);
    121 }
    122 void tarjan(int u, int d)
    123 {
    124     vv[u] = 1;
    125     dis[u] = d;
    126     pa[u] = u;
    127     if(u > bcc_cnt)
    128                dis[u]++;
    129      for(int i = 0; i < query[u].size(); i++)
    130      {
    131          int v = query[u][i].first;
    132          int id = query[u][i].second;
    133          if(vis[v])
    134             ans[id] = dis[u] + dis[v] - 2*dis[findset(v)] + (findset(v) > bcc_cnt);
    135      }
    136      for(int i = 0; i < g[u].size(); i++)
    137      {
    138          int v = g[u][i];
    139          if(!vv[v])
    140          {
    141              tarjan(v, dis[u]);
    142              pa[v] = u;
    143          }
    144      }
    145 }
    146 int main(void)
    147 {
    148     int n, m;
    149     while(scanf("%d%d", &n, &m), n||m)
    150     {
    151         for(int i = 0; i < maxn; i++)
    152             adj[i].clear(), g[i].clear(), query[i].clear();
    153             memset(flag, -1, sizeof(flag));
    154         for(int i = 1; i <= m; i++)
    155         {
    156             int u, v;
    157             scanf("%d%d", &u, &v);
    158             u--, v--;
    159             adj[u].pb(mp(i, v));
    160             adj[v].pb(mp(i, u));
    161             ee[i].u = u, ee[i].v = v;
    162         }
    163         find_bcc(n);
    164         int cut_cnt = 0;
    165         for(int i = 0; i < n; i++)
    166             if(iscut[i])
    167         {
    168             cut_cnt++;
    169             int u = cut_cnt+bcc_cnt;
    170             for(int k = 0; k < adj[i].size(); k++)
    171             {
    172                 int v = ebccno[adj[i][k].first];
    173                 if(flag[v] != u )
    174                 {
    175                     flag[v] = u;
    176                     g[v].pb(u);
    177                     g[u].pb(v);
    178                 }
    179             }
    180         }
    181         int q;
    182         for(int i = scanf("%d", &q); i <= q; i++)
    183         {
    184             int s, t;
    185             scanf("%d%d", &s, &t);
    186             s = ebccno[s], t = ebccno[t];
    187             query[s].pb(mp(t, i));
    188             query[t].pb(mp(s, i));
    189         }
    190         memset(vv, 0, sizeof(vv));
    191         for(int i = 1; i <= bcc_cnt+cut_cnt; i++)
    192             if(!vv[i])
    193         tarjan(i, 0);
    194         for(int i = 1; i <= q; i++)
    195             printf("%d
    ", ans[i]);
    196     }
    197     return 0;
    198 }
    View Code

    这个也可用Sparse  Table(ST算法)结合RMQ求解LCA

    下面是代码:

      1 #include <iostream>
      2 #include <sstream>
      3 #include <cstdio>
      4 #include <climits>
      5 #include <cstring>
      6 #include <cstdlib>
      7 #include <string>
      8 #include <stack>
      9 #include <map>
     10 #include <cmath>
     11 #include <vector>
     12 #include <queue>
     13 #include <algorithm>
     14 #define esp 1e-6
     15 #define pi acos(-1.0)
     16 #define pb push_back
     17 #define lson l, m, rt<<1
     18 #define rson m+1, r, rt<<1|1
     19 #define mp(a, b) make_pair((a), (b))
     20 #define in  freopen("in.txt", "r", stdin);
     21 #define out freopen("out.txt", "w", stdout);
     22 #define print(a) printf("%d
    ",(a));
     23 #define bug puts("********))))))");
     24 #define stop  system("pause");
     25 #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
     26 #define inf 0x0f0f0f0f
     27 
     28 using namespace std;
     29 typedef long long  LL;
     30 typedef vector<int> VI;
     31 typedef pair<int, int> pii;
     32 typedef vector<pii> VII;
     33 typedef vector<pii, int> VIII;
     34 typedef VI:: iterator IT;
     35 #define eid first
     36 #define vtx second
     37 
     38 const int maxn = 10000 + 10000;
     39 const int maxm = 100000 + 10000;
     40 int pre[maxn], low[maxn], bccno[maxn], ebccno[maxm], iscut[maxn], vis[maxm], ans[maxn], pa[maxn], bcc_cnt, dfs_clock;
     41 int dep[maxn], E[maxn], R[maxn];
     42 int dp[maxn*2][30];
     43 VI g[maxn], bcc[maxn];
     44 VII adj[maxn], query[maxn];
     45 struct edge
     46 {
     47     int u, v;
     48 } ee[maxm];
     49 stack<int> S;
     50 int cnt;
     51 int dfs(int u, int fa)
     52 {
     53     int lowu = pre[u] = ++dfs_clock;
     54     int child = 0;
     55     for(int i = 0; i < adj[u].size(); i++)
     56     {
     57         int v = adj[u][i].vtx;
     58         if(!pre[v])
     59         {
     60             S.push(adj[u][i].eid);
     61             child++;
     62             vis[adj[u][i].eid] = 1;
     63             int lowv = dfs(v, u);
     64             lowu = min(lowu, lowv);
     65             if(lowv >= pre[u])
     66             {
     67                 iscut[u] = 1;
     68                 bcc_cnt++;
     69                 bcc[bcc_cnt].clear();
     70                 for(;;)
     71                 {
     72                     int e = S.top();
     73                     S.pop();
     74                     bcc[bcc_cnt].pb(e);
     75                     ebccno[e] = bcc_cnt;
     76                     bccno[ee[e].u] = bccno[ee[e].v] = bcc_cnt;
     77                     if(e == adj[u][i].eid)  break;
     78                 }
     79             }
     80         }
     81         else if(pre[v] < pre[u])
     82         {
     83             if(v != fa)
     84             {
     85                 lowu = min(lowu, pre[v]);
     86                 S.push(adj[u][i].eid);
     87                 vis[adj[u][i].eid] = 1;
     88             }
     89             else
     90             {
     91                 if( !vis[adj[u][i].eid])
     92                 {
     93                     lowu = min(lowu, pre[v]);
     94                     S.push(adj[u][i].eid);
     95                     vis[adj[u][i].eid] = 1;
     96                 }
     97             }
     98         }
     99     }
    100     if(fa < 0 && child == 1)
    101     {
    102         iscut[u] = 0;
    103     }
    104     return low[u] = lowu;
    105 }
    106 void find_bcc(int n)
    107 {
    108     memset(pre, 0, sizeof(pre));
    109     memset(bccno, 0, sizeof(bccno));
    110     memset(iscut, 0, sizeof(iscut));
    111     memset(ebccno, 0, sizeof(ebccno));
    112     memset(vis, 0, sizeof(vis));
    113 
    114     while(!S.empty()) S.pop();
    115     dfs_clock = bcc_cnt = 0;
    116     for(int i = 0; i < n ; i++)
    117         if(!pre[i])
    118             dfs(i, -1);
    119 }
    120 int flag[maxn];
    121 int dis[maxn];
    122 int vv[maxn];
    123 int findset(int x)
    124 {
    125     return pa[x] == x ? x : pa[x] = findset(pa[x]);
    126 }
    127 void ST(int u, int d, int sum)
    128 {
    129     vv[u] = 1;
    130     R[u] = ++cnt;
    131     dep[cnt] = d;
    132     E[cnt] = u;
    133     dis[u] = sum;
    134     if(u > bcc_cnt)
    135         dis[u]++;
    136     for(int i = 0; i < g[u].size(); i++)
    137     {
    138         int v = g[u][i];
    139         if(!vv[v])
    140         {
    141             ST(v, d+1, dis[u]);
    142             E[++cnt] = u;
    143             dep[cnt] = d;
    144         }
    145     }
    146 }
    147 void Init(void)
    148 {
    149     for(int i = 1; i <= cnt; i++)
    150         dp[i][0] = i;
    151     for(int j = 1; j <= (int)(log(cnt)/log(2.0)); j++)
    152         for(int i = 1; i + (1<<j) - 1 <= cnt; i++)
    153         {
    154             if(dep[dp[i][j-1]] < dep[dp[i+(1<<(j-1))][j-1]])
    155                 dp[i][j] = dp[i][j-1];
    156             else dp[i][j] = dp[i + (1<<(j-1))][j-1];
    157         }
    158 }
    159 int RMQ(int u, int v)
    160 {
    161     int k = (int)(log(v - u + 1)/log(2.0));
    162     if(dep[dp[u][k]] < dep[dp[v - (1<<k) + 1][k]])
    163         return dp[u][k];
    164     return dp[v - (1<<k) + 1][k];
    165 }
    166 int main(void)
    167 {
    168     
    169     int n, m;
    170     while(scanf("%d%d", &n, &m), n||m)
    171     {
    172         for(int i = 0; i < maxn; i++)
    173             adj[i].clear(), g[i].clear(), query[i].clear();
    174         memset(flag, -1, sizeof(flag));
    175         for(int i = 1; i <= m; i++)
    176         {
    177             int u, v;
    178             scanf("%d%d", &u, &v);
    179             u--, v--;
    180             adj[u].pb(mp(i, v));
    181             adj[v].pb(mp(i, u));
    182             ee[i].u = u, ee[i].v = v;
    183         }
    184         find_bcc(n);
    185         int cut_cnt = 0;
    186         for(int i = 0; i < n; i++)
    187             if(iscut[i])
    188             {
    189                 cut_cnt++;
    190                 int u = cut_cnt+bcc_cnt;
    191                 for(int k = 0; k < adj[i].size(); k++)
    192                 {
    193                     int v = ebccno[adj[i][k].first];
    194                     if(flag[v] != u )
    195                     {
    196                         flag[v] = u;
    197                         g[v].pb(u);
    198                         g[u].pb(v);
    199                     }
    200                 }
    201             }
    202         memset(vv, 0, sizeof(vv));
    203         cnt = 0;
    204         for(int i = 1; i <= bcc_cnt+cut_cnt; i++)
    205             if(!vv[i])
    206                 ST(i, 0, 0);
    207         int q;
    208         Init();//记得初始化啊  。。。。。。。。
    209         for(int i = scanf("%d", &q); i <= q; i++)
    210         {
    211             int s, t;
    212             scanf("%d%d", &s, &t);
    213             s = ebccno[s], t = ebccno[t];
    214             int ss , tt;
    215             ss = min(R[s], R[t]);
    216             tt = max(R[s], R[t]);
    217             int lca = RMQ(ss, tt);
    218             lca = E[lca];
    219             int ans = dis[s] + dis[t] - 2 * dis[lca] + (lca > bcc_cnt);
    220             printf("%d
    ", ans);
    221         }
    222     }
    223     return 0;
    224 }
    View Code

    两者时间上差不多,而且ST算法需要初始化,更容易出错

  • 相关阅读:
    DataTablez转List对象效率慢的问题.
    Oracle 删除重复数据
    1.layui 添加旋转等待, 2.div里面加载HTML页面
    layui-table JSON.stringify()序列化出来的不同行数据类型错误.导致后台转成表格的时候出错.(常用)
    0基础学MVC课程
    构造函数的执行顺序
    html控件自动点 “加号”添加 多个附件
    C#委托之个人理解 转自 loose_went
    一步一步学Linq to sql系列文章 转lovecherry
    使用AOP 使C#代码更清晰 转yanghua_kobe
  • 原文地址:https://www.cnblogs.com/rootial/p/3366178.html
Copyright © 2020-2023  润新知