【CF】121 Div.1 C. Fools and Roads
2015-09-23 22:11
459 查看
题意是给定一棵树。同时,给定如下k个查询:
给出任意两点u,v,对u到v的路径所经过的边进行加计数。
k个查询后,分别输出各边的计数之和。
思路利用LCA,对cnt[u]++, cnt[v]++,并对cnt[LCA(u, v)] -= 2.
然后dfs求解各边的计数。
给出任意两点u,v,对u到v的路径所经过的边进行加计数。
k个查询后,分别输出各边的计数之和。
思路利用LCA,对cnt[u]++, cnt[v]++,并对cnt[LCA(u, v)] -= 2.
然后dfs求解各边的计数。
/* 191C */ #include <iostream> #include <string> #include <map> #include <queue> #include <set> #include <stack> #include <vector> #include <deque> #include <algorithm> #include <cstdio> #include <cmath> #include <ctime> #include <cstring> #include <climits> #include <cctype> #include <cassert> #include <functional> #include <iterator> #include <iomanip> using namespace std; //#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int> #define stpii set<pair<int, int> > #define mpii map<int,int> #define vi vector<int> #define pii pair<int,int> #define vpii vector<pair<int,int> > #define rep(i, a, n) for (int i=a;i<n;++i) #define per(i, a, n) for (int i=n-1;i>=a;--i) #define clr clear #define pb push_back #define mp make_pair #define fir first #define sec second #define all(x) (x).begin(),(x).end() #define SZ(x) ((int)(x).size()) #define lson l, mid, rt<<1 #define rson mid+1, r, rt<<1|1 const int maxn = 1e5+5; const int maxd = 17; vpii E[maxn]; bool visit[maxn]; int ans[maxn]; int cnt[maxn]; int deep[maxn]; int pre[maxn][maxd]; void dfs(int u, int fa) { int sz = SZ(E[u]), v; deep[u] = deep[fa] + 1; rep(i, 0, sz) { v = E[u][i].fir; if (v == fa) continue; pre[v][0] = u; rep(j, 1, maxd) pre[v][j] = pre[pre[v][j-1]][j-1]; dfs(v, u); } } int LCA(int u, int v) { if (deep[u] > deep[v]) swap(u, v); if (deep[u] < deep[v]) { int tmp = deep[v] - deep[u]; rep(i, 0, maxd) { if (tmp & (1<<i)) v = pre[v][i]; } } if (u != v) { per(i, 0, maxd) { if (pre[u][i] != pre[v][i]) { u = pre[u][i]; v = pre[v][i]; } } return pre[u][0]; } else { return u; } } int dfs2(int u, int eid) { int ret = 0, sz = SZ(E[u]); int e, v; visit[u] = true; rep(i, 0, sz) { v = E[u][i].fir; e = E[u][i].sec; if (!visit[v]) { ret += dfs2(v, e); } } ret += cnt[u]; ans[eid] = ret; return ret; } int main() { ios::sync_with_stdio(false); #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); freopen("data.out", "w", stdout); #endif int n; int u, v, fa; scanf("%d", &n); rep(i, 1, n) { scanf("%d %d", &u, &v); E[u].pb(mp(v, i)); E[v].pb(mp(u, i)); } dfs(1, 0); int k; scanf("%d", &k); while (k--) { scanf("%d %d", &u, &v); fa = LCA(u, v); ++cnt[u]; ++cnt[v]; cnt[fa] -= 2; } dfs2(1, 0); rep(i, 1, n) printf("%d ", ans[i]); putchar('\n'); #ifndef ONLINE_JUDGE printf("time = %d.\n", (int)clock()); #endif return 0; }
相关文章推荐
- 写一个函数返回参数二进制中 1 的个数
- angularjs[1.4.3]
- Spring RabbitMq概述
- springmvc之helloworld
- 指向指针的指针
- css.day02.eg
- 安卓软键盘的自动弹起/隐藏
- ORA-00923: 未找到要求的 FROM 关键字
- C语言中,为什么字符串可以赋值给字符指针变量
- 数据报(UDP)套接字客户端/服务器编程
- 去除inline或inline-block标签间隙的方法
- win7与VMware ubuntu虚拟机实现文件共享
- 排序算法一:直接插入排序
- struts2 自定义类型转换器
- 类的加法
- ThinkPHP中Session用法详解
- java GET请求与POST请求
- Linux复习笔记(一) -- Bash的基本操作
- uva 1175 - Ladies' Choice(稳定婚姻问题)
- Android屏幕适配全攻略(最权威的官方适配指导)