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. python爬取酒店信息练习

    爬取酒店信息,首先知道要用到那些库.本次使用request库区获取网页,使用bs4来解析网页,使用selenium来进行模拟浏览. 本次要爬取的美团网的蚌埠酒店信息及其评价.爬取的网址为“http:/ ...

  2. jsonp封装成promise

    首先将jsonp通过npm 安装引入js文件中,代码如下 import originJsonp from 'jsonp' export default function jsonp(url, data ...

  3. “2017面向对象程序设计(Java)第十一周学习总结”存在问题的反馈及教学安排

    “2017面向对象程序设计(Java)第十一周学习总结”存在问题的反馈及教学安排1.“提出表扬的同学:姜依萍,王雪玲,徐楠,相文君,赵晓未提交作业的同学:任红强,王瑞强,宗鹏新,扎西才让,布旦刀杰,范 ...

  4. java.security.MessageDigest (2) 生成安全令牌!

    时候,我们需要产生一个数据,这个数据保存了用户的信息,但加密后仍然有可能被人使用,即便他人不确切的了解详细信息... 好比,我们在上网的时候,很多网页都会有一个信息,是否保存登录信息,以便下次可以直接 ...

  5. 虚拟机 安装 CentOS7

    初次接触CentOS,最好是在虚拟机中安装: 因为CentOS的安装选项有很多,不理解的情况下千万不要在物理机上尝试: 不然可能出现这种情况:安装好以后,只有黑色的屏幕,只能在里面敲命令:这对于新手来 ...

  6. 苹果笔记本 如何配置成php开发系统

    方法一 启动内置的apace 打开终端输入命令 停止服务:sudo /usr/sbin/apachectl stop 开启服务:sudo /usr/sbin/apachectl start 重启服务: ...

  7. eclipse jvm配置

    Eclipse设置JVM参数:->Run Configurations ->VM arguments,如下:

  8. NYOJ-1058 DFS部分求和

    原题链接 本题思路:暴力深搜,具体见代码. #include <iostream> #include <stack> using namespace std; + ; int ...

  9. Django配置后台xadmin管理界面

    Django配置后台xadmin管理界面 python版本3.6.5 Django版本1.10.8(刚开始是2.1.5,由于各种错误,改成了低版本) 1.xadmin的安装,下载地址https://g ...

  10. sqlite 数据库错误 The database disk image is malformed database disk image

    收银机上的sqlite数据库经常出现这种错误,错误的原因有可能是突然断电或是一些不规范操作导致的. 网上一般的做法有两种: 方法一: 1.在https://www.sqlite.org/downloa ...