Codeforces278E Tourists
来自FallDream的博客,未经允许,请勿转载,谢谢。
给定一张无向图,有点权,要支持单点修改点权和询问从一个点到另一个点不重复经过节点的路径上点权最小值的最小值。
n,m<=10^5
考虑求出图的点双连通分量,然后每个点向所有包含他的点双连边,这样我们可以得到一棵树。
询问就变成了询问与树上两点间路径上的点相邻的点中权值的最小值。
我们考虑对每个点双开一个堆,把所有儿子的信息扔进去。这样但点修改只需要修改它父亲那个点双就行了。
然后用树剖+线段树来支持查询即可。注意特判lca的父亲节点。
复杂度O(nlog^2n)
- #include<iostream>
- #include<cstring>
- #include<cstdio>
- #include<vector>
- #include<queue>
- #include<map>
- #define P(x,y) make_pair(min(x,y),max(x,y))
- #define pa pair<int,int>
- #define MN 200000
- #define N 262144
- using namespace std;
- inline int read()
- {
- int x=,f=;char ch=getchar();
- while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
- while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
- return x*f;
- }
- pa q[MN*+];map<pa,bool> mp;vector<int> v[MN+];priority_queue<pa,vector<pa>,greater<pa> > s[MN+];
- int n,m,Q,tp=,b[MN+],head[MN+],dfn[MN+],low[MN+],mark[MN+],dn=,cnt=,size[MN+];
- int fa[MN+],w[MN+],vis[MN+],num=,bel[MN+],dep[MN+],top[MN+],mx[MN+],T[N*+];
- struct edge{int to,next;}e[MN*+];
- inline void ins(int f,int t)
- {
- e[++cnt]=(edge){t,head[f]};head[f]=cnt;
- e[++cnt]=(edge){f,head[t]};head[t]=cnt;
- }
- inline void Ins(int f,int t)
- {
- v[f].push_back(t);
- v[t].push_back(f);
- }
- void Tarjan(int x,int fa)
- {
- dfn[x]=low[x]=++dn;int son=;
- for(int i=head[x];i;i=e[i].next)
- if(e[i].to!=fa)
- {
- if(!dfn[e[i].to])
- {
- ++son;
- q[++tp]=make_pair(x,e[i].to),Tarjan(e[i].to,x);
- low[x]=min(low[x],low[e[i].to]);
- if(low[e[i].to]>=dfn[x])
- {
- b[x]=;++num;
- while(q[tp+]!=make_pair(x,e[i].to))
- {
- int a=q[tp].first,b=q[tp].second;
- if(bel[a]!=num) Ins(a,num+n);
- if(bel[b]!=num) Ins(b,num+n);
- --tp;bel[a]=num;bel[b]=num;
- }
- }
- }
- else
- {
- low[x]=min(low[x],dfn[e[i].to]);
- if(dfn[x]>dfn[e[i].to]) q[++tp]=make_pair(x,e[i].to);
- }
- }
- if(son==&&!fa) b[x]=;
- }
- void Pre(int x,int f)
- {
- fa[x]=f;size[x]=;mx[x]=;
- for(int i=;i<v[x].size();++i)
- if(v[x][i]!=f)
- {
- dep[v[x][i]]=dep[x]+;
- Pre(v[x][i],x);
- size[x]+=size[v[x][i]];
- if(size[v[x][i]]>size[mx[x]]) mx[x]=v[x][i];
- }
- }
- void Dfs(int x,int Tp)
- {
- top[x]=Tp;dfn[x]=++dn;
- if(mx[x]) Dfs(mx[x],Tp);
- for(int i=;i<v[x].size();++i)
- if(v[x][i]!=mx[x]&&v[x][i]!=fa[x])
- Dfs(v[x][i],v[x][i]);
- }
- void Renew(int x,int k){for(T[x+=N]=k;x>>=;)T[x]=min(T[x<<],T[x<<|]);}
- int Query(int l,int r)
- {
- int mx=1e9;
- for(l+=N-,r+=N+;l^r^;l>>=,r>>=)
- {
- if(~l&) mx=min(mx,T[l+]);
- if( r&) mx=min(mx,T[r-]);
- }
- return mx;
- }
- void Add(int x,int v,int k)
- {
- ++vis[v];
- s[x].push(make_pair(k,v));
- while(!s[x].empty()&&w[s[x].top().second]!=s[x].top().first) s[x].pop();
- int K=s[x].size()?s[x].top().first:;Renew(dfn[x],K);
- }
- int Solve(int x,int y)
- {
- int mx=1e9;
- while(top[x]!=top[y])
- {
- if(dep[top[x]]<dep[top[y]]) swap(x,y);
- mx=min(mx,Query(dfn[top[x]],dfn[x]));
- x=fa[top[x]];
- }
- if(dfn[x]>dfn[y]) swap(x,y);
- mx=min(mx,Query(dfn[x],dfn[y]));
- if(x>n&&fa[x]) mx=min(mx,w[fa[x]]);
- return mx;
- }
- char st[];
- int main()
- {
- n=read();m=read();Q=read();
- for(int i=;i<=n;++i) w[i]=read();
- for(int i=;i<=m;++i) ins(read(),read());
- Tarjan(,);memset(T,,sizeof(T));
- dn=;Pre(,);Dfs(,);
- for(int i=;i<=n;++i)
- {
- Renew(dfn[i],w[i]);
- if(fa[i]) Add(fa[i],i,w[i]);
- }
- for(int i=;i<=Q;++i)
- {
- scanf("%s",st+);int x=read(),y=read();
- if(st[]=='A') printf("%d\n",Solve(x,y));
- else
- {
- w[x]=y,Renew(dfn[x],y);
- if(fa[x]) Add(fa[x],x,y);
- }
- }
- return ;
- }
Codeforces278E Tourists的更多相关文章
- 【Codefoces487E/UOJ#30】Tourists Tarjan 点双连通分量 + 树链剖分
E. Tourists time limit per test: 2 seconds memory limit per test: 256 megabytes input: standard inpu ...
- Tourists
Tourists 时间限制: 5 Sec 内存限制: 64 MB 题目描述 In Tree City, there are n tourist attractions uniquely labele ...
- CF487 E. Tourists [点双连通分量 树链剖分 割点]
E. Tourists 题意: 无向连通图 C a w: 表示 a 城市的纪念品售价变成 w. A a b: 表示有一个游客要从 a 城市到 b 城市,你要回答在所有他的旅行路径中最低售价的最低可能值 ...
- 【CF487E】Tourists(圆方树)
[CF487E]Tourists(圆方树) 题面 UOJ 题解 首先我们不考虑修改,再来想想这道题目. 我们既然要求的是最小值,那么,在经过一个点双的时候,走的一定是具有较小权值的那一侧. 所以说,我 ...
- 每日英语:Foreign Tourists Skip Beijing
Overseas tourists continued to shun Beijing through 2013. shun:避开,避免,回避 Amid rising pollution and a ...
- L192 Virgin Galactic Completes Test of Spaceship to Carry Tourists
Virgin Galactic says its spacecraft designed to launch tourists into space completed an important te ...
- UOJ #30. [CF Round #278] Tourists
UOJ #30. [CF Round #278] Tourists 题目大意 : 有一张 \(n\) 个点, \(m\) 条边的无向图,每一个点有一个点权 \(a_i\) ,你需要支持两种操作,第一种 ...
- [UOJ30]/[CF487E]Tourists
[UOJ30]/[CF487E]Tourists 题目大意: 一个\(n(n\le10^5)\)个点\(m(m\le10^5)\)条边的无向图,每个点有点权.\(q(q\le10^5)\)次操作,操作 ...
- Tourists——圆方树
CF487E Tourists 一般图,带修求所有简单路径代价. 简单路径,不能经过同一个点两次,那么每个V-DCC出去就不能再回来了. 所以可以圆方树,然后方点维护一下V-DCC内的最小值. 那么, ...
随机推荐
- 团队作业4——第一次项目冲刺(Alpha版本)11.16
a. 提供当天站立式会议照片一张 举行站立式会议,讨论项目安排: 整理各自的任务汇报: 全分享遇到的困难一起讨论: 讨论接下来的计划: b. 每个人的工作 (有work item 的ID) 1.前两天 ...
- Flask 学习 十 博客文章
提交和显示博客文章 app/models.py 文章模型 class Post(db.Model): __tablename__ = 'posts' id = db.Column(db.Integer ...
- 【iOS】swift 枚举
枚举语法 你可以用enum开始并且用大括号包含整个定义体来定义一个枚举: enum SomeEnumeration { // 在这里定义枚举 } 这里有一个例子,定义了一个包含四个方向的罗盘: enu ...
- bzoj千题计划288:bzoj1876: [SDOI2009]SuperGCD
http://www.lydsy.com/JudgeOnline/problem.php?id=1876 高精压位GCD 对于 GCD(a, b) a>b 若 a 为奇数,b 为偶数,GCD ...
- c 语言的基本语法
1,c的令牌(Tokens) printf("Hello, World! \n"); 这五个令牌是: printf ( "Hello, World! \n" ) ...
- RxJava系列7(最佳实践)
RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...
- (Sqlyog或Navicat不友好处)SHOW ENGINE INNODB STATUS 结果为空或结果为=====================================
因为最近在学习innodb引擎,所以就在自己的sqlyog上执行上述命令: SHOW ENGINE INNODB STATUS 结果显示如下: 换了个客户端navicat,执行如下: 最后登录到服务器 ...
- POJ2398【判断点在直线哪一侧+二分查找区间】
题意:同POJ2318 #include<algorithm> #include<cstdio> #include<cstdlib> #include<cst ...
- C#使用Gecko实现浏览器
Gecko就是火狐浏览器的内核啦,速度很快,兼容性比.net内置的webbrowser高到不知哪里去了. 使用Gecko首先要下载一堆依赖库,主要是Skybound.Gecko和xulrunner. ...
- [转][scrapy] CannotListenError: Couldn’t listen on [Errno 98] Address already in use.
[scrapy] CannotListenError: Couldn't listen on [Errno 98] Address already in use. python eason 1年前 ...