CodeForces 487E UOJ 30 Tourists Tarjan + 树链剖分
来源:互联网 发布:手机网络主播招聘 编辑:程序博客网 时间:2024/05/16 15:27
施工中。。。
以下代码需要C++11才可编译。。
#include <cstdio>#include <algorithm>#include <functional>#include <set>#include <cstring>using namespace std;#define FOR(i,j,k) for(i=j;i<=k;i++)int read() { int s = 0, f = 1; char ch = getchar(); for (; '0' > ch || ch > '9'; ch = getchar()) if (ch == '-') f = -1; for (; '0' <= ch && ch <= '9'; ch = getchar()) s = s * 10 + ch - '0'; return s * f;}const int N = 100001, M = 2 * N;struct Graph { int head[N], next[M], to[M], cnt; Graph() : cnt(0) {} void add(int u, int v) { next[++cnt] = head[u]; head[u] = cnt; to[cnt] = v; next[++cnt] = head[v]; head[v] = cnt; to[cnt] = u; }};struct BCC : Graph { int dfn[N], low[N], id[N], belong[N], cut[N], cnt; multiset<int> val[M]; BCC() { cnt = 0; } function<void(int,int)> found_cut_point; void tarjan(int u) { static int ts = 0, top = 0; static int stack[N]; int x, i; dfn[u] = low[u] = ++ts; stack[++top] = u; for (i = head[u]; i; i = next[i]) if (!dfn[to[i]]) { tarjan(to[i]); low[u] = min(low[u], low[to[i]]); if (dfn[u] == low[to[i]]) { cnt ++; cut[u] = 1; do { x = stack[top--]; id[x] = cnt; if (cut[x]) found_cut_point(x, cnt); } while(x != to[i]); found_cut_point(u, cnt); } } else low[u] = min(low[u], dfn[to[i]]); }} bcc;struct SegmentTree { int initial[M], mi[M]; int build(int t, int l, int r) { if (l == r) return mi[t] = initial[l]; int mid = l + r >> 1; return mi[t] = min(build(t * 2, l, mid), build(t * 2 + 1, mid + 1, r)); } int query(int t, int l, int r, int ql, int qr) { if (l == ql && r == qr) return mi[t]; int mid = l + r >> 1; if (qr <= mid) return query(t * 2, l, mid, ql, qr); else if (ql > mid) return query(t * 2 + 1, mid + 1, r, ql, qr); else return min(query(t * 2, l, mid, ql, mid), query(t * 2 + 1, mid + 1, r, mid + 1, qr)); } void modify(int t, int l, int r, int x, int v) { if (l == r) { mi[t] = v; return; } int mid = l + r >> 1; if (x <= mid) modify(t * 2, l, mid, x, v); else modify(t * 2 + 1, mid + 1, r, x, v); mi[t] = min(mi[t * 2], mi[t * 2 + 1]); }} seg;struct Tree : Graph { int son[N], sz[N], top[N], dep[N], pos[N], fa[N], id; SegmentTree *st; Tree() { id = 0; } void dfs1(int x) { son[x] = 0; sz[x] = 1; for (int i = head[x]; i; i = next[i]) if (to[i] != fa[x]) { fa[to[i]] = x; dep[to[i]] = dep[x] + 1; dfs1(to[i]); sz[x] += sz[to[i]]; if (sz[to[i]] > sz[son[x]]) son[x] = to[i]; } } void dfs2(int x, int t) { top[x] = t; pos[x] = ++id; if (son[x]) dfs2(son[x], t); for (int i = head[x]; i; i = next[i]) if (to[i] != fa[x] && to[i] != son[x]) dfs2(to[i], to[i]); } int lca(int x, int y) { int fx = top[x], fy = top[y]; while (fx != fy) { if (dep[fx] < dep[fy]) swap(fx, fy), swap(x, y); x = fa[fx], fx = top[x]; } if (dep[x] > dep[y]) swap(x, y); return x; } int query(int x, int y) { int fx = top[x], fy = top[y], ans = 2147483647; while (fx != fy) { if (dep[fx] < dep[fy]) swap(fx, fy), swap(x, y); ans = min(ans, st->query(1, 1, id, pos[fx], pos[x])); x = fa[fx], fx = top[x]; } if (dep[x] > dep[y]) swap(x, y); return min(ans, st->query(1, 1, id, pos[x], pos[y])); }} tree;int main() { static int w[N]; char ch[2]; int n = read(), m = read(), q = read(), i, x, y; FOR (i, 1, n) w[i] = read(); tree.st = &seg; bcc.found_cut_point = [n] (int id, int bcc) { tree.add(id + n, bcc); }; while (m--) bcc.add(read(), read()); bcc.tarjan(1); FOR (i, 1, n) { if (i != 1) bcc.val[bcc.id[i]].insert(w[i]); if (bcc.cut[i]) bcc.val[n + i].insert(2147483647); } tree.dfs1(n+1); tree.dfs2(n+1, n+1); memset(seg.initial, 127, sizeof seg.initial); FOR (i, 1, 2*n) if(tree.pos[i]) seg.initial[tree.pos[i]] = *bcc.val[i].begin(); seg.build(1, 1, tree.id); while (q--) { scanf("%s%d%d", ch, &x, &y); if (ch[0] == 'C') { if (x != 1) { bcc.val[bcc.id[x]].erase(bcc.val[bcc.id[x]].find(w[x])); bcc.val[bcc.id[x]].insert(y); seg.modify(1, 1, tree.id, tree.pos[bcc.id[x]], *bcc.val[bcc.id[x]].begin()); } w[x] = y; } else { if (x == y) printf("%d\n", w[x]); else { x=bcc.cut[x] ? x + n : bcc.id[x]; y=bcc.cut[y] ? y + n : bcc.id[y]; int l = tree.lca(x, y); if (l <= bcc.cnt) l = tree.fa[l]; printf("%d\n", min(w[l - n], tree.query(x, y)); } } } return 0;}
There are n cities in Cyberland, numbered from 1 to n, connected by m bidirectional roads. The j-th road connects city ajand bj.
For tourists, souvenirs are sold in every city of Cyberland. In particular, city i sell it at a price of wi.
Now there are q queries for you to handle. There are two types of queries:
- "C a w": The price in city a is changed to w.
- "A a b": Now a tourist will travel from city a to b. He will choose a route, he also doesn't want to visit a city twice. He will buy souvenirs at the city where the souvenirs are the cheapest (possibly exactly at city a or b). You should output the minimum possible price that he can buy the souvenirs during his travel.
More formally, we can define routes as follow:
- A route is a sequence of cities [x1, x2, ..., xk], where k is a certain positive integer.
- For any 1 ≤ i < j ≤ k, xi ≠ xj.
- For any 1 ≤ i < k, there is a road connecting xi and xi + 1.
- The minimum price of the route is min(wx1, wx2, ..., wxk).
- The required answer is the minimum value of the minimum prices of all valid routes from a to b.
The first line of input contains three integers n, m, q (1 ≤ n, m, q ≤ 105), separated by a single space.
Next n lines contain integers wi (1 ≤ wi ≤ 109).
Next m lines contain pairs of space-separated integers aj and bj (1 ≤ aj, bj ≤ n, aj ≠ bj).
It is guaranteed that there is at most one road connecting the same pair of cities. There is always at least one valid route between any two cities.
Next q lines each describe a query. The format is "C a w" or "A a b" (1 ≤ a, b ≤ n, 1 ≤ w ≤ 109).
For each query of type "A", output the corresponding answer.
3 3 31231 22 31 3A 2 3C 1 5A 2 3
12
7 9 412345671 22 51 52 33 42 45 66 75 7A 2 3A 6 4A 6 7A 3 3
2153
For the second sample, an optimal routes are:
From 2 to 3 it is [2, 3].
From 6 to 4 it is [6, 5, 1, 2, 4].
From 6 to 7 it is [6, 5, 7].
From 3 to 3 it is [3].
- CodeForces 487E UOJ 30 Tourists Tarjan + 树链剖分
- [Codeforces 487E]Tourists/[JZOJ4691]旅行/[UOJ#30]Tourists
- codeforces E. Tourists (树链剖分+tarjan)
- CodeForces 487E Tourists
- CodeForces - 487E Tourists
- Codeforces 487E Tourists
- UOJ #30. 【CF Round #278】Tourists Tarjan+树链剖分
- 【codeforces】487E. Tourists 点双连通+树链剖分
- [点双连通分量 缩点 树链剖分] Codeforces 487E #278 (Div. 1) E. Tourists
- 【UOJ #30】【CF Round #278】Tourists
- [Codeforces487E]Tourists(Tarjan+树链剖分+STL)
- CF 487E Tourists(JZOJ4691 旅行) 树链剖分维护点双连通分量信息
- codeforces 286D Tourists
- [UOJ 220]网格:Tarjan
- 【题解】[codeforces round #198 div2]Tourists problem
- CodeForces 567E President and Roads(最短路 + tarjan)
- 【Tarjan】UOJ#146 【NOIP2015】信息传递
- 【OJ相关】validator (UOJ / codeforces)
- 数据包接收系列 — 下半部实现(软中断)
- 我的青春,我的梦
- WebView中常见问题总结
- 2015中国数据库大会Mongodb分享
- 水仙花数
- CodeForces 487E UOJ 30 Tourists Tarjan + 树链剖分
- phonegap-调用android手机照相机
- Android开发App架构MVP模式
- APP中通过包名或类名启动另一个APP
- EditText状态变化——选中和未先中(底部变颜色的线)
- linux 定时任务
- C代码:指定路径删除N天之前的日志
- PAT 1019. General Palindromic Number (20)
- jquery事件委托off与on连用无效的问题