zoukankan      html  css  js  c++  java
  • 【HDOJ】3686 Traffic Real Time Query System

    这题做了几个小时,基本思路肯定是求两点路径中的割点数目,思路是tarjan缩点,然后以割点和连通块作为新节点见图。转化为lca求解。
    结合点——双连通分量与LCA。

      1 /* 3686 */
      2 #include <iostream>
      3 #include <sstream>
      4 #include <string>
      5 #include <map>
      6 #include <queue>
      7 #include <set>
      8 #include <stack>
      9 #include <vector>
     10 #include <deque>
     11 #include <algorithm>
     12 #include <cstdio>
     13 #include <cmath>
     14 #include <ctime>
     15 #include <cstring>
     16 #include <climits>
     17 #include <cctype>
     18 #include <cassert>
     19 #include <functional>
     20 #include <iterator>
     21 #include <iomanip>
     22 using namespace std;
     23 //#pragma comment(linker,"/STACK:102400000,1024000")
     24 
     25 #define sti                set<int>
     26 #define stpii            set<pair<int, int> >
     27 #define mpii            map<int,int>
     28 #define vi                vector<int>
     29 #define pii                pair<int,int>
     30 #define vpii            vector<pair<int,int> >
     31 #define rep(i, a, n)     for (int i=a;i<n;++i)
     32 #define per(i, a, n)     for (int i=n-1;i>=a;--i)
     33 #define clr                clear
     34 #define pb                 push_back
     35 #define mp                 make_pair
     36 #define fir                first
     37 #define sec                second
     38 #define all(x)             (x).begin(),(x).end()
     39 #define SZ(x)             ((int)(x).size())
     40 #define lson            l, mid, rt<<1
     41 #define rson            mid+1, r, rt<<1|1
     42 
     43 typedef struct {
     44     int u, v, f, nxt;
     45 } edge_t;
     46 
     47 typedef struct {
     48     int v, nxt;
     49 } edge;
     50 
     51 const int maxv = 10005;
     52 const int maxe = 200005;
     53 int head[maxv], l, top;
     54 int pre[maxv], low[maxv];
     55 bool iscut[maxv];
     56 int cnt[maxv], dfs_clock, bcc_cnt;
     57 int bn[maxe];
     58 int S[maxe];
     59 vi bcc[maxv];
     60 edge_t E[maxe];
     61 int n, m;
     62 
     63 const int maxvv = maxv * 2;
     64 int mark[maxvv];
     65 int head_[maxvv], l_;
     66 int cutn[maxvv];
     67 edge E_[maxe];
     68 
     69 int deep[maxvv], beg[maxvv];
     70 int V[maxvv<<1], D[maxvv<<1];
     71 
     72 int dp[16][maxvv<<1];
     73 
     74 void init_() {
     75     memset(head_, -1, sizeof(head_));
     76     memset(mark, 0, sizeof(mark));
     77     l_ = 0;
     78 }
     79 
     80 void addEdge_(int u, int v) {
     81     E_[l_].v = v;
     82     E_[l_].nxt = head_[u];
     83     head_[u] = l_++;
     84     
     85     E_[l_].v = u;
     86     E_[l_].nxt = head_[v];
     87     head_[v] = l_++;
     88 }
     89 
     90 void init() {
     91     l = dfs_clock = bcc_cnt = top = 0;
     92     memset(head, -1, sizeof(head));
     93     memset(iscut, false, sizeof(iscut));
     94     memset(cnt, 0, sizeof(cnt));
     95     memset(cutn, 0, sizeof(cutn));
     96     memset(pre, 0, sizeof(pre));
     97     rep(i, 1, n+1)
     98         bcc[i].clr();
     99 }
    100 
    101 void addEdge(int u, int v) {
    102     E[l].u = u;
    103     E[l].f = 0;
    104     E[l].v = v;
    105     E[l].nxt = head[u];
    106     head[u] = l++;
    107 
    108     E[l].u = v;
    109     E[l].f = 0;
    110     E[l].v = u;
    111     E[l].nxt = head[v];
    112     head[v] = l++;
    113 }
    114 
    115 void tarjan(int u, int fa) {
    116     int v, k;
    117 
    118     low[u] = pre[u] = ++dfs_clock;
    119     for (k=head[u]; k!=-1; k=E[k].nxt) {
    120         if (E[k].f)
    121             continue;
    122         E[k].f = E[k^1].f = 1;
    123         v = E[k].v;
    124         S[top++] = k;
    125         if (!pre[v]) {
    126             tarjan(v, u);
    127             low[u] = min(low[u], low[v]);
    128             if (low[v] >= pre[u]) {
    129                 iscut[u] = true;
    130                 ++cnt[u];
    131                 bcc_cnt++;
    132                 while (1) {
    133                     int kk = S[--top];
    134                     bn[kk>>1] = bcc_cnt;
    135                     bcc[E[kk].u].pb(bcc_cnt);
    136                     bcc[E[kk].v].pb(bcc_cnt);
    137                     if (kk == k)
    138                         break;
    139                 }
    140             }
    141         } else {
    142             low[u] = min(low[u], pre[v]);
    143         }
    144     }
    145 }
    146 
    147 void dfs(int u, int fa, int d) {
    148     mark[u] = dfs_clock;
    149     deep[u] = d;
    150     V[++top] = u;
    151     D[top] = d;
    152     beg[u] = top;
    153 
    154     int v, k;
    155 
    156     for (k=head_[u]; k!=-1; k=E_[k].nxt) {
    157         v = E_[k].v;
    158         if (v == fa)
    159             continue;
    160         dfs(v, u, d+1);
    161         V[++top] = u;
    162         D[top] = d;
    163     }
    164 }
    165 
    166 void init_RMQ(int n) {
    167     int i, j;
    168 
    169     for (i=1; i<=n; ++i)
    170         dp[0][i] = i;
    171     for (j=1; (1<<j)<=n; ++j)
    172         for (i=1; i+(1<<j)-1<=n; ++i)
    173             if (D[dp[j-1][i]] < D[dp[j-1][i+(1<<(j-1))]])
    174                 dp[j][i] = dp[j-1][i];
    175             else
    176                 dp[j][i] = dp[j-1][i+(1<<(j-1))];
    177 }
    178 
    179 int RMQ(int l, int r) {
    180     if (l > r)
    181         swap(l, r);
    182 
    183     int k = 0;
    184 
    185     while (1<<(k+1) <= r-l+1)
    186         ++k;
    187 
    188     if (D[dp[k][l]] < D[dp[k][r-(1<<k)+1]])
    189         return V[dp[k][l]];
    190     else
    191         return V[dp[k][r-(1<<k)+1]];
    192 }
    193 
    194 void solve() {
    195     int u, v, lca;
    196     
    197     rep(i, 1, n+1) {
    198         if (!pre[i]) {
    199             tarjan(i, -1);
    200             if (cnt[i] <= 1)
    201                 iscut[i] = false;
    202         }
    203     }
    204 
    205     int cid = bcc_cnt;
    206     
    207     init_();
    208     cid = bcc_cnt;
    209     for (u=1; u<=n; ++u) {
    210         if (!iscut[u])
    211             continue;
    212         sort(all(bcc[u]));
    213         cutn[++cid] = 1;
    214         addEdge_(cid, bcc[u][0]);
    215         int sz = SZ(bcc[u]);
    216         rep(i, 1, sz) {
    217             if (bcc[u][i] != bcc[u][i-1]) {
    218                 addEdge_(cid, bcc[u][i]);
    219             }
    220         }
    221     }
    222 
    223     top = 0;
    224     ++dfs_clock;
    225     rep(i, 1, cid+1) {
    226         if (mark[i] != dfs_clock)
    227             dfs(i, 0, 0);
    228     }
    229 
    230     init_RMQ(top);
    231 
    232     int q;
    233     int ans;
    234 
    235     scanf("%d", &q);
    236     while (q--) {
    237         scanf("%d %d", &u, &v);
    238         u = bn[u-1];
    239         v = bn[v-1];
    240         lca = RMQ(beg[u], beg[v]);
    241         ans = (deep[u]+deep[v] - deep[lca]*2 + 1) / 2;
    242         printf("%d
    ", ans);
    243     }
    244 }
    245 
    246 int main() {
    247     ios::sync_with_stdio(false);
    248     #ifndef ONLINE_JUDGE
    249         freopen("data.in", "r", stdin);
    250         freopen("data.out", "w", stdout);
    251     #endif
    252 
    253     int u, v;
    254 
    255     while (scanf("%d %d", &n, &m)!=EOF && (n||m)) {
    256         init();
    257         rep(i, 0, m) {
    258             scanf("%d %d", &u, &v);
    259             addEdge(u, v);
    260         }
    261 
    262         solve();
    263     }
    264 
    265     #ifndef ONLINE_JUDGE
    266         printf("time = %d.
    ", (int)clock());
    267     #endif
    268 
    269     return 0;
    270 }
  • 相关阅读:
    ORACLE数据库备份与恢复详解
    Oracle块,区,段
    Oracle触发器
    SQL
    Oracle 用户管理权限
    Mybatis_One
    面向对象编程应用实例
    面向对象之方法2
    面向对象之方法1
    面向对象之结构体2
  • 原文地址:https://www.cnblogs.com/bombe1013/p/5183686.html
Copyright © 2011-2022 走看看