CodeVs 1036 商务旅行
2015-11-24 22:49
232 查看
http://codevs.cn/problem/1036/
LCA 模板
不知道为什么用模拟链表存边就 TLE 两组数据,vector 就过了 0.0
稀疏表
Tarjan
LCA 模板
不知道为什么用模拟链表存边就 TLE 两组数据,vector 就过了 0.0
稀疏表
#include <stdio.h> #include <vector> #include <algorithm> #include <cmath> using std::vector; const int MAXN = 30000 + 5; const int MAXNN = MAXN << 1; vector<vector<int> > G; void initG(int n) { G.clear(); G.resize(n + 1); } int euler[MAXNN]; int depth[MAXNN]; int firstIn[MAXN]; void dfs(int u, int f, int& timestamp, int d) { euler[timestamp] = u; depth[u] = d; firstIn[u] = timestamp++; for (int i = 0; i < (int) G[u].size(); i++) { int v = G[u][i]; if (v == f) continue; dfs(v, u, timestamp, d + 1); euler[timestamp++] = u; } } #define POW(i) (1 << (i)) int stable[32][MAXNN]; void initRmq(int n) { for (int i = 0; i < n; i++) stable[0][i] = euler[i]; for (int j = 1; POW(j) <= n; j++) { for (int i = 0; i + POW(j) <= n; i++) { int x = stable[j - 1][i]; int y = stable[j - 1][i + POW(j - 1)]; stable[j][i] = depth[x] > depth[y] ? y : x; } } } int lca(int u, int v) { int i = firstIn[u]; int j = firstIn[v]; if (i > j) std::swap(i, j); int k = log2(j - i + 1); int x = stable[k][i]; int y = stable[k][j - POW(k) + 1]; int result = depth[x] > depth[y] ? y : x; return result; } int main() { int n; scanf("%d", &n); initG(n); int u, v; for (int i = 1; i < n; i++) { scanf("%d %d", &u, &v); G[u].push_back(v); G[v].push_back(u); } int timestamp = 0; dfs(1, -1, timestamp, 0); initRmq(timestamp); int sum = 0; int m; scanf("%d", &m); u = 1; for (int i = 1; i <= m; i++) { scanf("%d", &v); sum += depth[u] + depth[v] - 2 * depth[lca(u, v)]; u = v; } printf("%d\n", sum); return 0; }
Tarjan
#include <stdio.h> #include <vector> #include <string.h> using namespace std; const int MAXN = 30000 + 5; vector<vector<int> > G; void initEdges(int n) { G.clear(); G.resize(n + 1); } int id[MAXN]; int rnk[MAXN]; void initSets(int n) { for (int i = 1; i <= n; i++) { id[i] = i; rnk[i] = 1; } } int root(int i) { if (i == id[i]) return i; return id[i] = root(id[i]); } void unionSet(int x, int y) { if (rnk[x] > rnk[y]) id[y] = x; else id[x] = y, rnk[y] += (rnk[x] == rnk[y]); } vector<vector<int> > query; void inputQuery(int n) { query.clear(); query.resize(n + 1); int m; scanf("%d", &m); for (int u = 1, v = 1; m--; ) { scanf("%d", &v); query[u].push_back(v); query[v].push_back(u); u = v; } } int ancestor[MAXN]; bool vis[MAXN]; int depth[MAXN]; void initTarjan(int n) { initSets(n); memset(vis, 0, sizeof(vis)); for (int i = 1; i <= n; i++) ancestor[i] = i; } void tarjan(int u, int f, int& sum, int d) { depth[u] = d; for (int i = 0; i < (int) G[u].size(); i++) { int v = G[u][i]; if (v == f) continue; tarjan(v, u, sum, d + 1); int rootU = root(u); int rootV = root(v); if (rootV != rootU) unionSet(rootU, rootV); ancestor[root(u)] = u; } vis[u] = true; for (int i = 0; i < (int) query[u].size(); i++) { int v = query[u][i]; if (!vis[v]) continue; int dis = depth[u] + depth[v] - 2 * depth[ancestor[root(v)]]; sum += dis; } } int main() { int n; scanf("%d", &n); initEdges(n); int u, v; for (int i = 0; i < n - 1; i++) { scanf("%d %d", &u, &v); G[u].push_back(v); G[v].push_back(u); } inputQuery(n); initTarjan(n); int sum = 0; tarjan(1, -1, sum, 0); printf("%d\n", sum); return 0; }
相关文章推荐
- 有关创业团队和执行力的想法
- Webpack 转自http://segmentfault.com/a/1190000002551952
- Linux 下源码安装大杂烩
- 使用ExpandableListView实现一个时光轴
- 使用Source Insight查看Android Framework 源码
- 使用ExpandableListView实现一个时光轴
- 使用ExpandableListView实现一个时光轴
- 飞花的鱼塘
- LintCode:搜索旋转排序数组
- 手动安装liberty版本openstack环境(allinone)---安装数据库及rabbitmq
- Mina框架的使用
- js实现接收表单的值并将值拼在表单action后面的方法
- leetcode Generate Parentheses python
- 使用ExpandableListView实现一个时光轴
- Mac下配置环境变量
- IntelliJ IDEA font fix
- java 的搭建开发环境的简单介绍
- 领域驱动设计之基本概念
- swift willset didset get set区别
- iOS开发多线程-线程安全