Solution

先Tarjan求出点双联通分量 并缩点。 用$multiset$维护 点双内的最小点权。

容易发现, 点双内的最小点权必须包括与它相连的割边的点权。 所以我们必须想办法来维护。

所以考虑用割点的点权更新它的父节点, 这样查询 点双 内的最小点权只需要查询本身的 $multiset$ 和 它的父亲节点就可以了。

最后加个树剖就能过啦!

Code

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<vector>
#define rd read()
using namespace std; const int N = 2e5 + ;
const int inf = ~0U >> ; int Head[N << ], Tot;
int head[N], tot;
int low[N], dfn[N], cnt, col, c[N], nd_num, cut[N];
int st[N], tp;
int n, m, Q, a[N];
int f[N << ], top[N << ], sz[N << ], son[N << ], mk, id[N << ], dep[N << ]; vector<int> q[N];
multiset<int> S[N << ]; struct edge {
int nxt, to;
}e[N << ], E[N << ]; int read() {
int X = , p = ; char c = getchar();
for (; c > '' || c < ''; c = getchar())
if (c == '-') p = -;
for (; c >= '' && c <= ''; c = getchar())
X = X * + c - '';
return X * p;
} void add(int u, int v) {
e[++tot].to = v;
e[tot].nxt = head[u];
head[u] = tot;
} void Add(int u, int v) {
E[++Tot].to = v;
E[Tot].nxt = Head[u];
Head[u] = Tot;
} void tarjan(int u) {
low[u] = dfn[u] = ++cnt;
st[++tp] = u;
int flag = ;
for (int i = head[u]; i; i = e[i].nxt) {
int nt = e[i].to;
if (!dfn[nt]) {
tarjan(nt);
low[u] = min(low[u], low[nt]);
if (low[nt] < dfn[u])
continue;
col++; flag++;
cut[u] = ;
for (; tp;) {
int z = st[tp--];
q[col].push_back(z);
if (z == nt)
break;
}
q[col].push_back(u);
}
else low[u] = min(low[u], dfn[nt]);
}
if (flag < && u == )
cut[u] = ;
} namespace SegT { int MIN[N << ]; #define mid ((l + r) >> 1)
#define lson nd << 1
#define rson nd << 1 | 1 void up(int nd) {
MIN[nd] = min(MIN[lson], MIN[rson]);
} void modify(int pos, int d, int l, int r, int nd) {
if (l == r) {
MIN[nd] = d;
return;
}
if (pos <= mid)
SegT::modify(pos, d, l, mid, lson);
else
SegT::modify(pos, d, mid + , r, rson);
SegT::up(nd);
}
int query(int L, int R, int l, int r, int nd) {
if (L <= l && r <= R)
return MIN[nd];
int tmp = inf;
if(L <= mid)
tmp = min(tmp, SegT::query(L, R, l, mid, lson));
if(mid < R)
tmp = min(tmp, SegT::query(L, R, mid + , r, rson));
return tmp;
} #undef mid
#undef lson
#undef rson
} namespace SP { void dfs1(int u) {
sz[u] = ;
for (int i = Head[u]; i; i = E[i].nxt) {
int nt = E[i].to;
if (nt == f[u])
continue;
f[nt] = u;
dep[nt] = dep[u] + ;
SP::dfs1(nt);
sz[u] += sz[nt];
if(sz[nt] >= sz[son[u]])
son[u] = nt;
}
} void dfs2(int u) {
id[u] = ++mk;
if (!son[u])
return;
top[son[u]] = top[u];
SP::dfs2(son[u]);
for (int i = Head[u]; i; i = E[i].nxt) {
int nt = E[i].to;
if (nt == f[u] || nt == son[u])
continue;
top[nt] = nt;
SP::dfs2(nt);
}
} int query(int x, int y) {
int re = inf, tmp;
for (; top[x] != top[y];) {
if (dep[top[x]] < dep[top[y]])
swap(x, y);
tmp = SegT::query(id[top[x]], id[x], , mk, );
re = min(tmp, re);
x = f[top[x]];
}
if (dep[x] < dep[y])
swap(x, y);
tmp = SegT::query(id[y], id[x], , mk, );
re = min(tmp, re);
if (f[y] && y <= col)
tmp = SegT::query(id[f[y]], id[f[y]], , mk, );
re = min(tmp, re);
return re;
}
} int main()
{
n = rd; m = rd; Q = rd;
for (int i = ; i <= n; ++i)
a[i] = rd;
for (int i = ; i <= m; ++i) {
int u = rd, v = rd;
add(u, v); add(v, u);
}
tarjan();
nd_num = col;
for (int i = ; i <= n; ++i)
if (cut[i]) c[i] = ++nd_num;
for (int i = ; i <= col; ++i)
for (int j = , len = q[i].size(); j < len; ++j) {
int x = q[i][j];
if (cut[x])
Add(c[x], i), Add(i, c[x]);
else c[x] = i;
}
dep[] = ;
SP::dfs1();
top[] = ;
SP::dfs2();
for (int i = ; i <= n; ++i) {
int x = c[i];
S[x].insert(a[i]);
if(x > col)
S[f[x]].insert(a[i]);
}
for (int i = ; i <= nd_num; ++i) {
int x = *S[i].begin();
SegT::modify(id[i], x, , mk, );
}
for (; Q; Q--) {
char ch = getchar();
while (ch != 'A' && ch != 'C')
ch = getchar();
int u = rd, v = rd;
if (ch == 'C') {
swap(v, a[u]);
S[c[u]].erase(S[c[u]].find(v));
S[c[u]].insert(a[u]);
int x = *S[c[u]].begin();
SegT::modify(id[c[u]], x, , mk, );
if (c[u] <= col)
continue;
S[f[c[u]]].erase(S[f[c[u]]].find(v));
S[f[c[u]]].insert(a[u]);
x = *S[f[c[u]]].begin();
SegT::modify(id[f[c[u]]], x, , mk, );
}
else {
if (u == v) printf("%d\n", a[u]);
else printf("%d\n", SP::query(c[u], c[v]));
}
}
}

CF487E Tourists - Tarjan缩点 + 树剖 + multiset的更多相关文章

  1. CF487E Tourists【圆方树+tarjan+multiset+树剖+线段树】

    圆方树不仅能解决仙人掌问题(虽然我仙人掌问题也没用过圆方树都是瞎搞过去的),还可以解决一般图的问题 一般图问题在于缩完环不是一棵树,所以就缩点双(包括双向边) 每个方点存他所在点双内除根以外的点的最小 ...

  2. CF487E Tourists 【圆方树 + 树剖 + 堆】

    题目链接 CF487E 题解 圆方树 + 树剖 裸题 建好圆方树维护路径上最小值即可 方点的值为其儿子的最小值,这个用堆维护 为什么只维护儿子?因为这样修改点的时候就只需要修改其父亲的堆 这样充分利用 ...

  3. CF487E Tourists(圆方树+堆+链剖)

    本题解并不提供圆方树讲解. 所以不会圆方树的出门右转问yyb 没有修改的话圆方树+链剖. 方点的权值为点双连通分量里的最小值. 然后修改的话圆点照修,每一个方点维护一个小根堆. 考虑到可能被菊花卡死. ...

  4. poj3694 Network[边双缩点+树剖/并查集]

    首先同一个点双内部的加边肯定不影响..所以先缩点成树,然后每次加一条边,这条对应的树上路径上所有边就都不是桥了,且每次操作独立作用,不相互影响(不过有可能本来一条边已经不是桥了又被标记了一次),所以每 ...

  5. cf1000E We Need More Bosses (tarjan缩点+树的直径)

    题意:无向联通图,求一条最长的路径,路径长度定义为u到v必须经过的边的个数 如果把强联通分量都缩成一个点以后,每个点内部的边都是可替代的:而又因为这是个无向图,缩完点以后就是棵树,跑两遍dfs求直径即 ...

  6. F - Warm up HDU - 4612 tarjan缩点 + 树的直径 + 对tajan的再次理解

    题目链接:https://vjudge.net/contest/67418#problem/F 题目大意:给你一个图,让你加一条边,使得原图中的桥尽可能的小.(谢谢梁学长的帮忙) 我对重边,tarja ...

  7. LUOGU P2416 泡芙 (缩点+树剖)

    传送门 解题思路 首先先缩点,然后将缩完点的权值改成点中路径为1的条数,然后再将边权下放到点权上,求一个每个点到根的路径和,然后用树上2点距离公式算..刚开始写的线段树,T了2个点. #include ...

  8. HDU4612+Tarjan缩点+BFS求树的直径

    tarjan+缩点+树的直径题意:给出n个点和m条边的图,存在重边,问加一条边以后,剩下的桥的数量最少为多少.先tarjan缩点,再在这棵树上求直径.加的边即是连接这条直径的两端. /* tarjan ...

  9. CF487E Tourists + 圆方树学习笔记(圆方树+树剖+线段树+multiset)

    QWQ果然我已经什么都学不会的人了. 这个题目要求的是图上所有路径的点权和!QWQ(我只会树上啊!) 这个如果是好啊 这时候就需要 圆方树! 首先在介绍圆方树之前,我们先来一点简单的前置知识 首先,我 ...

随机推荐

  1. JAVA第五周 动手动脑

    public class Example { int x = 3;//类的实例变量,初始化值为3 static int y = 4;//类的静态变量,初始化值为4 public static void ...

  2. gradle 很好用的么

    Gradle 其实是很好用的 2017, Apr 14 by Tesla Ice Zhang Gradle 是一款使用 Kotlin (划掉) Groovy 编写的 JVM 构建工具,其易用性和 Ma ...

  3. idea gradle卡主问题

    http://services.gradle.org/distributions/  首先下载 all 版本 ,解压 ,再d盘, 并保留zip 文件  ,新建环境变量 GRADLE_HOME   指向 ...

  4. canvas画布内部重复画圆

    <!DOCTYPE html><html><head> <title>canvas example</title> <meta cha ...

  5. Maximum Likelihood及Maximum Likelihood Estimation

    1.What is Maximum Likelihood? 极大似然是一种找到最可能解释一组观测数据的函数的方法. Maximum Likelihood is a way to find the mo ...

  6. msf客户端渗透(二):PDF漏洞、恶意网站、flash漏洞、IE漏洞、java漏洞、android漏洞、VBScript感染payload

    这个漏洞利用只在XP上有效 利用pdf漏洞利用payload exploit生成一个pdf文件 传到被攻击机上 启动msf侦听 exploit -j XP上双击运行这个pdf时,kali获取到一个sh ...

  7. HttpSession 和 HttpSession

    说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案.

  8. SpringCloud报错:Caused by: org.yaml.snakeyaml.parser.ParserException: while parsing MappingNode

    今天在配置eureka集群时,SpringCloud报错如下: Caused by: org.yaml.snakeyaml.parser.ParserException: while parsing ...

  9. Win7系统不能记忆窗口大小与位置解决方法

    似在某此系统优化后,无意发现系统在注销或重启后,打开资源管理器,它以默认大小及位置显示. 对于习惯自定义操作来说,甚为不便,遍找方法未有奏效者,但总萦绕心头,时时记起. 今日再找问题解决方法,难兄难弟 ...

  10. OC 线程操作1 - pthread

    #import "ViewController.h" #import <pthread.h> //1.需要包含这个头文件 @interface ViewControll ...