• BZOJ 3331 [BeiJing2013]压力-Tarjan + 树上差分


    Solution

    Tarjan 点双缩点, 加上树上差分计算。

    注意特判。。。 我特判挂了好久呜呜呜

    Code

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #include<vector>
      5 #define rd read()
      6 using namespace std;
      7 
      8 const int N = 1e5 + 5;
      9 const int M = 2e5 + 5;
     10 const int base = 30;
     11 
     12 int head[N], tot;
     13 int Head[N << 1], Tot;
     14 int low[N], dfn[N], cnt, col, c[N], cut[N], n, m, Q;
     15 int f[N << 2][30], nd, id[N], idf[N << 2], dep[N << 2];
     16 int st[N], tp, num[N], sum[N << 2];
     17 
     18 vector<int> q[N << 1];
     19 
     20 struct edge {
     21     int nxt, to;
     22 }e[M << 1], E[M << 3];
     23 
     24 int read() {
     25     int X = 0, p = 1; char c = getchar();
     26     for (; c > '9' || c < '0'; c = getchar()) if (c == '-') p = -1;
     27     for (; c >= '0' && c <= '9'; c = getchar()) X = X * 10 + c - '0';
     28     return X * p;
     29 }
     30 
     31 void add(int u, int v) {
     32     e[++tot].to = v;
     33     e[tot].nxt = head[u];
     34     head[u] = tot;
     35 }
     36 
     37 void Add(int u, int v) {
     38     E[++Tot].to = v;
     39     E[Tot].nxt = Head[u];
     40     Head[u] = Tot;
     41 }
     42 
     43 void tarjan(int u) {
     44     low[u] = dfn[u] = ++cnt;
     45     st[++tp] = u;
     46     int flag = 0;
     47     for (int i = head[u]; i; i = e[i].nxt) {
     48         int nt = e[i].to;
     49         if (!dfn[nt]) {
     50             tarjan(nt);
     51             low[u] = min(low[u], low[nt]);
     52             if (low[nt] >= dfn[u]) {
     53                 flag++;
     54                 if (flag > 1 || u - 1)
     55                     cut[u] = 1;
     56                 col++;
     57                 for (; tp;) {
     58                     int v = st[tp--];
     59                     q[col].push_back(v);
     60                     if (v == nt)
     61                         break;
     62                 }
     63                 q[col].push_back(u);
     64             }
     65         }
     66         else low[u] = min(low[u], dfn[nt]);
     67     }
     68 }
     69 
     70 void dfs(int u) {
     71     for (int i = Head[u]; i; i = E[i].nxt) {
     72         int nt = E[i].to;
     73         if (f[u][0] == nt)
     74             continue;
     75         f[nt][0] = u;
     76         dep[nt] = dep[u] + 1;
     77         dfs(nt);
     78     }
     79 }
     80 
     81 int LCA(int x, int y) {
     82     if (dep[x] < dep[y])
     83         swap(x, y);
     84     for (int k = base - 1; ~k; --k)
     85         if (dep[f[x][k]] >= dep[y])
     86             x = f[x][k];
     87     if (x == y)
     88         return x;
     89     for (int k = base - 1; ~k; --k) 
     90         if (f[x][k] != f[y][k])
     91             x = f[x][k], y = f[y][k];
     92     return f[x][0];
     93 }
     94 
     95 void dfs2(int u) {
     96     for (int i = Head[u]; i; i = E[i].nxt) {
     97         int nt = E[i].to;
     98         if (nt == f[u][0]) 
     99             continue;
    100         dfs2(nt);
    101         sum[u] += sum[nt];
    102     }
    103     if(u > col)
    104         num[idf[u]] += sum[u];
    105 }
    106 
    107 int main()
    108 {
    109     //freopen("1.in","r", stdin);
    110     //freopen("out.out","w",stdout);
    111     n = rd; m = rd; Q = rd;
    112     for (int i = 1; i <= m; ++i) {
    113         int u = rd, v = rd;
    114         add(u, v); add(v, u);
    115     }
    116     tarjan(1);
    117     nd = col;
    118     for (int i = 1; i <= n; ++i)
    119         if (cut[i]) c[i] = ++nd, idf[nd] = i;
    120     for (int i = 1; i <= col; ++i) 
    121         for(int j = 0, len = q[i].size(); j < len; ++j) {
    122             int x = q[i][j];
    123             if (cut[x]) 
    124                 Add(i, c[x]), Add(c[x], i);
    125             else c[x] = i;
    126         }
    127     dep[1] = 1;
    128     dfs(1);
    129     for (int k = 1; k < base; ++k)
    130         for (int i = 1; i <= nd; ++i)
    131             f[i][k] = f[f[i][k - 1]][k - 1];
    132     for (; Q; Q--) {
    133         int u = rd, v = rd, lca;
    134         if (c[u] <= col) num[u]++; 
    135         if (c[v] <= col) num[v]++;
    136         u = c[u]; v = c[v];
    137         if (u == v) continue;
    138         lca = LCA(u, v);
    139         sum[v]++; sum[u]++;
    140         sum[lca]--; sum[f[lca][0]]--;
    141     }
    142     dfs2(1);
    143     for (int i = 1; i <= n; ++i)
    144         printf("%d
    ", num[i]);
    145 }
    View Code
  • 相关阅读:
    NOIP2016 蚯蚓 题解
    BZOJ 1294 围豆豆 题解
    POJ1852 Ants 题解
    BZOJ 1131 [POI2008] STA-Station 题解
    HDU 5963 朋友 题解
    Codeforces 1292C Xenon's Attack on the Gangs 题解
    Emergency Evacuation 题解
    P4408 逃学的小孩 题解
    UVA11300 Spreading the Wealth 题解
    P2882 Face The Right Way G 题解
  • 原文地址:https://www.cnblogs.com/cychester/p/9671378.html
Copyright © 2020-2023  润新知