Topic Link ~~>
To do the topic sentiment: This problem is done in hdu 5044 after feeling very simple.
Problem Solving Ideas:
First, the tree chain split, the tree is divided into chains, because the final question is all asked, so~ can be linear operation. After the tree chain is divided, there will be many chains, but each edge has a number, the equivalent of an array of linear operation, so that if the U ~ V to increase the 1, then you can make sum [u] + + 1; sum [v + 1]-= 1; This assumes that the number of V is large. At the end of the day, you just have to walk backwards one time and get all the results. With this understanding, the idea of a tree-chain split can be solved.
Code:
#include <iostream> #include <sstream> #include <map> #include <cmath> #include <fstream> #include <queue> #include <vector> #include <sstream> #include <cstring> #include <cstdio > #include <stack> #include <bitset> #include <ctime> #include <string> #include <cctype
> #include <iomanip> #include <algorithm> using namespace std;
#define INT __int64 #define L (x) (x * 2) #define R (x) (x * 2 + 1) const INT INF = 0x3f3f3f3f;
Const double ESP = 0.0000000001;
Const double PI = ACOs (-1.0);
const INT mod = 1e9 + 7;
const int MY = 1400 + 5;
const int MX = 100000 + 5;
int n, num, idx, m;
int HEAD[MX], sum[mx], ans[mx], p[mx], ti[mx], dep[mx], top[mx], siz[mx], son[mx], father[mx]; struct NODE {int u, v;}
E[MX]; struct Node {int V, next;}
E[MX*2]; void Addedge (int u, int v) {e[num].v = v; E[num].next = Head[u];
Head[u] = num++; E[NUM].V = u; E[num].next = Head[v]; HEAD[V] =num++;
} void Dfs_find (int u, int fa) {Dep[u] = Dep[fa] + 1;
Siz[u] = 1;
Son[u] = 0;
Father[u] = FA;
for (int i = head[u]; i =-1; i = e[i].next) {int v = E[I].V;
if (v = = FA) continue;
Dfs_find (V, u);
Siz[u] + = Siz[v];
if (Siz[son[u]] < SIZ[V]) son[u] = v;
}} void Dfs_time (int u, int fa) {Ti[u] = idx++;
Top[u] = FA;
if (Son[u]) dfs_time (Son[u], top[u]);
for (int i = head[u]; i =-1; i = e[i].next) {int v = E[I].V;
if (v = = Father[u] | | v = = Son[u]) continue;
Dfs_time (V, v); }} void LCA (int u, int v) {while (Top[u]! = Top[v]) {if (Dep[top[u]] < DEP[TOP[V]) swap
(U, v);
SUM[TI[U]+1]-= 1;
Sum[ti[top[u]] + = 1;
U = father[top[u]];
} if (Dep[u] > Dep[v]) Swap (U, v);
if (U = v) {Sum[ti[son[u]] + = 1;
SUM[TI[V]+1]-= 1; }} int main () {//Freopen ("Input.txt", "R", stdin);
int u, v;
while (~SCANF ("%d", &n)) {num = 0;
memset (head, -1, sizeof (head));
memset (sum, 0, sizeof (sum));
for (int i = 1; i < n; ++i) {scanf ("%d%d", &e[i].u, &E[I].V);
Addedge (e[i].u, E[I].V);
} dep[1] = siz[0] = 0;
Dfs_find (1, 1);
IDX = 1;
Dfs_time (1, 1);
scanf ("%d", &m);
for (int i = 0; i < m; ++i) {scanf ("%d%d", &u, &v);
LCA (U, v); } for (int i = 1; I <= n; ++i)//First Edge {if (dep[e[i].u] < DEP[E[I].V]) s
WAP (E[I].U, E[I].V);
P[TI[E[I].U]] = i;
} for (int i = 1; I <= n; ++i)//number of edges in Split {sum[i] + = sum[i-1];
Ans[p[i]] = sum[i];
} printf ("%d", ans[1]); for (int i = 2; i < n; ++i) prinTF ("%d", ans[i]);
Puts ("");
} return 0;
}