【CF】121 Div.1 C. Fools and Roads
题意是给定一棵树。同时,给定如下k个查询:
给出任意两点u,v,对u到v的路径所经过的边进行加计数。
k个查询后,分别输出各边的计数之和。
思路利用LCA,对cnt[u]++, cnt[v]++,并对cnt[LCA(u, v)] -= 2.
然后dfs求解各边的计数。
1 /* 191C */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <stack> 8 #include <vector> 9 #include <deque> 10 #include <algorithm> 11 #include <cstdio> 12 #include <cmath> 13 #include <ctime> 14 #include <cstring> 15 #include <climits> 16 #include <cctype> 17 #include <cassert> 18 #include <functional> 19 #include <iterator> 20 #include <iomanip> 21 using namespace std; 22 //#pragma comment(linker,"/STACK:102400000,1024000") 23 24 #define sti set<int> 25 #define stpii set<pair<int, int> > 26 #define mpii map<int,int> 27 #define vi vector<int> 28 #define pii pair<int,int> 29 #define vpii vector<pair<int,int> > 30 #define rep(i, a, n) for (int i=a;i<n;++i) 31 #define per(i, a, n) for (int i=n-1;i>=a;--i) 32 #define clr clear 33 #define pb push_back 34 #define mp make_pair 35 #define fir first 36 #define sec second 37 #define all(x) (x).begin(),(x).end() 38 #define SZ(x) ((int)(x).size()) 39 #define lson l, mid, rt<<1 40 #define rson mid+1, r, rt<<1|1 41 42 const int maxn = 1e5+5; 43 const int maxd = 17; 44 vpii E[maxn]; 45 bool visit[maxn]; 46 int ans[maxn]; 47 int cnt[maxn]; 48 int deep[maxn]; 49 int pre[maxn][maxd]; 50 51 void dfs(int u, int fa) { 52 int sz = SZ(E[u]), v; 53 54 deep[u] = deep[fa] + 1; 55 rep(i, 0, sz) { 56 v = E[u][i].fir; 57 if (v == fa) 58 continue; 59 pre[v][0] = u; 60 rep(j, 1, maxd) 61 pre[v][j] = pre[pre[v][j-1]][j-1]; 62 dfs(v, u); 63 } 64 } 65 66 int LCA(int u, int v) { 67 if (deep[u] > deep[v]) 68 swap(u, v); 69 if (deep[u] < deep[v]) { 70 int tmp = deep[v] - deep[u]; 71 rep(i, 0, maxd) { 72 if (tmp & (1<<i)) 73 v = pre[v][i]; 74 } 75 } 76 77 if (u != v) { 78 per(i, 0, maxd) { 79 if (pre[u][i] != pre[v][i]) { 80 u = pre[u][i]; 81 v = pre[v][i]; 82 } 83 } 84 return pre[u][0]; 85 } else { 86 return u; 87 } 88 } 89 90 int dfs2(int u, int eid) { 91 int ret = 0, sz = SZ(E[u]); 92 int e, v; 93 94 visit[u] = true; 95 rep(i, 0, sz) { 96 v = E[u][i].fir; 97 e = E[u][i].sec; 98 if (!visit[v]) { 99 ret += dfs2(v, e); 100 } 101 } 102 ret += cnt[u]; 103 ans[eid] = ret; 104 105 return ret; 106 } 107 108 int main() { 109 ios::sync_with_stdio(false); 110 #ifndef ONLINE_JUDGE 111 freopen("data.in", "r", stdin); 112 freopen("data.out", "w", stdout); 113 #endif 114 115 int n; 116 int u, v, fa; 117 118 scanf("%d", &n); 119 rep(i, 1, n) { 120 scanf("%d %d", &u, &v); 121 E[u].pb(mp(v, i)); 122 E[v].pb(mp(u, i)); 123 } 124 125 dfs(1, 0); 126 127 int k; 128 129 scanf("%d", &k); 130 while (k--) { 131 scanf("%d %d", &u, &v); 132 fa = LCA(u, v); 133 ++cnt[u]; 134 ++cnt[v]; 135 cnt[fa] -= 2; 136 } 137 138 dfs2(1, 0); 139 rep(i, 1, n) 140 printf("%d ", ans[i]); 141 putchar('\n'); 142 143 #ifndef ONLINE_JUDGE 144 printf("time = %d.\n", (int)clock()); 145 #endif 146 147 return 0; 148 }