cychester

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\n", num[i]);
145 }
View Code

 

posted on 2018-09-18 20:58  cychester  阅读(152)  评论(0编辑  收藏  举报

导航