Codeforces 191C Fools and Roads(树链拆分)
2015-09-22 18:56
344 查看
题目链接:Codeforces 191C Fools and Roads
题目大意:给定一个N节点的数。然后有M次操作,每次从u移动到v。问说每条边被移动过的次数。
解题思路:树链剖分维护边,用一个数组标记就可以,不须要用线段树。
题目大意:给定一个N节点的数。然后有M次操作,每次从u移动到v。问说每条边被移动过的次数。
解题思路:树链剖分维护边,用一个数组标记就可以,不须要用线段树。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1e5 + 5; int N, Q, ne, first[maxn], f[maxn], jump[maxn * 2]; int id, idx[maxn], top[maxn], far[maxn], son[maxn], dep[maxn], cnt[maxn]; struct Edge { int u, v; void set (int u, int v) { this->u = u; this->v = v; } }ed[maxn * 2]; void dfs (int u, int pre, int d) { far[u] = pre; dep[u] = d; cnt[u] = 1; son[u] = 0; for (int i = first[u]; i + 1; i = jump[i]) { int v = ed[i].v; if (v == pre) continue; dfs(v, u, d + 1); cnt[u] += cnt[v]; if (cnt[son[u]] < cnt[v]) son[u] = v; } } void dfs(int u, int rot) { top[u] = rot; idx[u] = ++id; if (son[u]) dfs(son[u], rot); for (int i = first[u]; i + 1; i = jump[i]) { int v = ed[i].v; if (v == far[u] || v == son[u]) continue; dfs(v, v); } } inline void add_Edge(int u, int v) { ed[ne].set(u, v); jump[ne] = first[u]; first[u] = ne++; } void init () { int u, v; ne = id = 0; memset(first, -1, sizeof(first)); scanf("%d", &N); for (int i = 1; i < N; i++) { scanf("%d%d", &u, &v); add_Edge(u, v); add_Edge(v, u); } dfs(1, 0, 0); dfs(1, 1); for (int i = 0; i < N - 1; i++) { int t = i * 2; if (dep[ed[t].u] < dep[ed[t].v]) swap(ed[t].u, ed[t].v); } } inline void add (int l, int r) { f[l]++, f[r + 1]--; } void solve (int u, int v) { int p = top[u], q = top[v]; while (p != q) { if (dep[p] < dep[q]) { swap(p, q); swap(u, v); } add(idx[p], idx[u]); u = far[p]; p = top[u]; } if (u == v) return; if (dep[u] > dep[v]) swap(u, v); add(idx[son[u]], idx[v]); } int main () { init(); scanf("%d", &Q); int u, v; while (Q--) { scanf("%d%d", &u, &v); solve(u, v); } int mv = 0; for (int i = 1; i <= N; i++) { mv += f[i]; f[i] = mv; } printf("%d", f[idx[ed[0].u]]); for (int i = 1; i < N - 1; i++) printf(" %d", f[idx[ed[i*2].u]]); printf("\n"); return 0; }
相关文章推荐
- android5.1判断外置SD卡是否存在
- ASCII,Unicode和UTF-8的辨识
- linux命令记录。(持续更新)
- mac创建公钥私钥
- JAVA正则表达式 Pattern和Matcher
- 一段解决了好多天疑惑的代码
- No CurrentSessionContext Configured!!
- MySQL入门教程 命令整合(亲测 配图)
- 01背包(DP)
- 物理引擎ODE
- linux下开发我所常用的命令
- CAN总线应用开发接口
- Redis configuration
- HDU 1890 区间反转
- 详细解读八大无线网络安全技术利弊
- [leetcode]Valid Number
- 第四周 建立单链表
- 自定义View,ViewGroup,SurfaceView
- mysql-5.6.25 配置和安装
- iOS超精细详解之GCD