[点双连通分量 缩点 树链剖分] Codeforces 487E #278 (Div. 1) E. Tourists
来源:互联网 发布:java商品信息管理系统 编辑:程序博客网 时间:2024/05/17 08:00
点双连通分量的缩点技巧
来自:http://blog.csdn.net/a_crazy_czy/article/details/52244069
在这里我们使用这样一种方法:对于每一个点双连通分量,我们建一个新建点储存点双所有点的最小权值,然后该点向点双内所有
注意到这棵树一定是普通点连向新建点连向普通点这样交替。修改的时候我们修改这个点自身的权值,还要把这个点所属的新建点(父亲节点)修改了。查询的时候呢?首先先查询两点之间路径的最小值,然后如果两点
为什么这样是对的呢?因为查询的时候,除了最顶端
关于怎么维护点双内最小值,对每一个新建点开一个
大概是这样 灵魂画作
#include<cstdio>#include<cstdlib>#include<algorithm>#include<stack>#include<set>#include<cstring>#define cl(x) memset(x,0,sizeof(x))using namespace std;inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++;}inline void read(int &x){ char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;}inline void read(char &x){ for (x=nc();x!='A' && x!='C';x=nc());}const int N=200005;struct SEG{ int T[N<<2],M; inline void Build(int n){ for (M=1;M<n+2;M<<=1); for (int i=2*M-1;i;i--) T[i]=1<<30; } inline void Modify(int s,int r){ T[s+=M]=r; while (s>>=1) T[s]=min(T[s<<1],T[s<<1|1]); } inline int Query(int s,int t){ int ret=1<<30; for (s+=M-1,t+=M+1;s^t^1;s>>=1,t>>=1){ if (~s&1) ret=min(ret,T[s^1]); if ( t&1) ret=min(ret,T[t^1]); } return ret; }}Seg;struct edge{ int u,v,next;}G[N<<4];int head1[N],head2[N],inum=1;int *head;inline void add(int u,int v,int p,int *head=::head){ G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;}stack<int> S;multiset<int> Set[100005];int pre[N],low[N],clk;#define V G[p].vint bcc;int n,m,val[N];inline void Tarjan(int u,int fa){ pre[u]=low[u]=++clk; S.push(u); for (int p=head[u];p;p=G[p].next) if (!pre[V]){ Tarjan(V,p); low[u]=min(low[u],low[V]); if (low[V]>=pre[u]){bcc++;add(u,n+bcc,++inum,head2),add(n+bcc,u,++inum,head2);while (1){ int x=S.top(); S.pop(); add(n+bcc,x,++inum,head2),add(x,n+bcc,++inum,head2); Set[bcc].insert(val[x]); if (x==V) break;} } }else if (p!=(fa^1)) low[u]=min(low[u],pre[V]);}int depth[N],size[N],fat[N];int tid[N],top[N];inline void dfs(int u,int fa){ depth[u]=depth[fa]+1; size[u]=1; fat[u]=fa; for (int p=head[u];p;p=G[p].next) if (V!=fa) dfs(V,u),size[u]+=size[V];}inline void find(int u,int fa,int z){ tid[u]=++clk; top[u]=z; int son=0,maxv=0; for (int p=head[u];p;p=G[p].next) if (V!=fa && size[V]>maxv) maxv=size[son=V]; if (son) find(son,u,z); for (int p=head[u];p;p=G[p].next) if (V!=fa && V!=son) find(V,u,V);}inline int Query(int u,int v){ int ret=1<<30; for (;top[u]!=top[v];u=fat[top[u]]){ if (depth[top[u]]<depth[top[v]]) swap(u,v); ret=min(ret,Seg.Query(tid[top[u]],tid[u])); } if (depth[u]>depth[v]) swap(u,v); ret=min(ret,Seg.Query(tid[u],tid[v])); int lca=u; if (lca>n) ret=min(ret,val[fat[lca]]); return ret;}int main(){ int Q,iu,iv; char order; freopen("t.in","r",stdin); freopen("t.out","w",stdout); read(n); read(m); read(Q); for (int i=1;i<=n;i++) read(val[i]); head=head1; for (int i=1;i<=m;i++) read(iu),read(iv),add(iu,iv,++inum),add(iv,iu,++inum); Tarjan(1,0); head=head2; clk=0; dfs(1,0); find(1,0,1); for (int i=1;i<=bcc;i++) val[n+i]=*Set[i].begin(); Seg.Build(n+bcc); for (int i=1;i<=n+bcc;i++) Seg.Modify(tid[i],val[i]); while (Q--){ read(order); read(iu); read(iv); if (order=='A') printf("%d\n",Query(iu,iv)); else{ if (fat[iu]){int fa=fat[iu];Set[fa-n].erase(Set[fa-n].find(val[iu]));Set[fa-n].insert(iv);val[fa]=*Set[fa-n].begin();Seg.Modify(tid[fa],val[fa]); } val[iu]=iv; Seg.Modify(tid[iu],val[iu]); } } return 0;}
0 0
- [点双连通分量 缩点 树链剖分] Codeforces 487E #278 (Div. 1) E. Tourists
- CF 487E Tourists(JZOJ4691 旅行) 树链剖分维护点双连通分量信息
- 【codeforces】487E. Tourists 点双连通+树链剖分
- CodeForces 652E|Pursuit For Artifacts|边双连通分量|缩点
- 点双连通分量
- 点双连通分量
- 点双连通分量
- 点双连通分量
- CodeForces 487E Tourists
- CodeForces - 487E Tourists
- Codeforces 487E Tourists
- Codeforces Beta Round #89 (Div. 2) E. Bertown roads(Tarjan、边双连通分量)
- poj 3177 双连通分量+缩点
- 点-双连通分量模板
- 求点双连通分量
- 点-双连通分量&边-双连通分量复习笔记
- 图论-桥/割点/双连通分量/缩点/LCA
- POJ 3177 Redundant Paths(边双连通分量+缩点)
- Android开发07_Service服务
- MySQL-5.7解压版(zip版)安装配置教程
- Leetcode 之 Swap Nodes in Pairs
- 剑指offer在线编程
- lintcode,翻转链表 II
- [点双连通分量 缩点 树链剖分] Codeforces 487E #278 (Div. 1) E. Tourists
- Jquery validate验证表单时多个name相同的元素只验证第一个的问题
- 贝叶斯分类算法
- glide加载图片
- “玲珑杯”ACM比赛 Round #7
- SSH框架之Hibernate的继承映射的形式二(三张表)
- Android实现推送方式解决方案
- Android系统权限和root权限
- 反转链表