BZOJ3331 [BeiJing2013]压力[圆方树+树上差分]
圆方树新技能get。具体笔记见图连通性问题学习笔记。
这题求无向图的必经点,这个是一个固定套路:首先,一张连通的无向图中,每对点双和点双之间是以一个且仅一个割点连接起来的(如果超过一个就不能是割点了),那么,在一个点双内部,从出发点开始,要走到另外一个点双中,这个中间的割点就是一条必经之路(没有其他路可以绕,否则这就有一个环了),所以,路上所有割点都是必经点,而点双内部走的话,由点双的定义,是至少有两条点不相交的路径的(当然两个点的点双的话直接没有中间点),所以中间非割点是可经而不是必经的。
所以,构建圆方树,起始点和终止点构成的路径上所有圆点就是答案。然后,依题意做树上差分即可。
为什么我线性求lca还跑不过log的啊。。
圆方树构建的code大致是模仿zsy写的。。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define mst(x) memset(x,0,sizeof x)
#define dbg(x) cerr << #x << " = " << x <<endl
#define dbg2(x,y) cerr<< #x <<" = "<< x <<" "<< #y <<" = "<< y <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=1e5+;
struct thxorz{
int to[N<<],nxt[N<<],head[N<<],tot;
inline void add(int x,int y){
to[++tot]=y,nxt[tot]=head[x],head[x]=tot;
to[++tot]=x,nxt[tot]=head[y],head[y]=tot;
}
}G1,G2,Q;
int n,m,q;
int tag[N<<],fa[N<<],anc[N<<],vis[N<<];
int Find(int x){return anc[x]==x?x:anc[x]=Find(anc[x]);}
#define y G2.to[j]
#define qy Q.to[j]
void tarjan_lca(int x,int fat){
anc[x]=x;fa[x]=fat;
for(register int j=G2.head[x];j;j=G2.nxt[j])if(fat^y)tarjan_lca(y,x),anc[y]=x;
vis[x]=;int tmp;
for(register int j=Q.head[x];j;j=Q.nxt[j])if(vis[qy])tmp=Find(qy),--tag[tmp],--tag[fa[tmp]];
}
void dfs(int x){for(register int j=G2.head[x];j;j=G2.nxt[j])if(fa[x]^y)dfs(y),tag[x]+=tag[y];}
#undef y
#undef qy
#define y G1.to[j]
int dfn[N],low[N],stk[N],Top,tim,cnt;
void tarjan(int x){//promise:connected,without vertexes isolated.
dfn[x]=low[x]=++tim;stk[++Top]=x;
for(register int j=G1.head[x];j;j=G1.nxt[j]){
if(!dfn[y]){//We needn't get the cut-vertexes,and cut-vertexes have nothing to do with v-DCCs.
tarjan(y),MIN(low[x],low[y]);
if(dfn[x]==low[y]){
int tmp;++cnt;
do tmp=stk[Top--],G2.add(tmp,cnt);while(tmp^y);
G2.add(x,cnt);
}
}
else MIN(low[x],dfn[y]);
}
}
#undef y
int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
cnt=read(n),read(m),read(q);
for(register int i=,x,y;i<=m;++i)read(x),read(y),G1.add(x,y);
for(register int i=;i<=n;++i)if(!dfn[i])Top=,tarjan(i);
for(register int i=,x,y;i<=q;++i)read(x),read(y),Q.add(x,y),++tag[x],++tag[y];
tarjan_lca(,);dfs();
for(register int i=;i<=n;++i)printf("%d\n",tag[i]);
return ;
}
总结:图中简单路径问题,经过点的统计问题,考虑从点双和圆方树入手。
顺带一提,点双缩点一般配合圆方树食用,而边双直接缩成一棵树,比如这题如果问必经边的话,一定是割边是必经边(证明同理),只要缩边双后在树上直接差分即可。
BZOJ3331 [BeiJing2013]压力[圆方树+树上差分]的更多相关文章
- BZOJ3331 压力 (圆方树+树上差分)
题意 略 题解 求路径上的割点. 然后就直接圆方树上差分 CODE #include <bits/stdc++.h> using namespace std; inline void rd ...
- 【题解】Uoj#30 Tourist(广义圆方树+树上全家桶)
[题解]Uoj#30 Tourist(广义圆方树+树上全家桶) 名字听起来很霸气其实算法很简单.... 仙人掌上的普通圆方树是普及题,但是广义圆方树虽然很直观但是有很多地方值得深思 说一下算法的流程: ...
- bzoj3331 压力(圆方树)
题目链接 圆方树 圆方树就是对于联通无向图中的每一个点双新建一个方点,与点双中的每个点连一条边,然后将原来的边删去.将原来的点看作圆点,新建的点看作方点.所以叫做圆方树. 性质 1.圆方树肯定是棵树( ...
- BZOJ 压力 tarjan 点双联通分量+树上差分+圆方树
题意 如今,路由器和交换机构建起了互联网的骨架.处在互联网的骨干位置的核心路由器典型的要处理100Gbit/s的网络流量. 他们每天都生活在巨大的压力之下.小强建立了一个模型.这世界上有N个网络设备, ...
- Codechef Sad Pairs——圆方树+虚树+树上差分
SADPAIRS 删点不连通,点双,圆方树 非割点:没有影响 割点:子树DP一下 有不同颜色,所以建立虚树 在圆方树上dfs时候 如果当前点是割点 1.统计当前颜色虚树上的不连通点对,树形DP即可 2 ...
- 仙人掌 && 圆方树 && 虚树 总结
仙人掌 && 圆方树 && 虚树 总结 Part1 仙人掌 定义 仙人掌是满足以下两个限制的图: 图完全联通. 不存在一条边处在两个环中. 其中第二个限制让仙人掌的题做 ...
- Note -「圆方树」学习笔记
目录 圆方树的定义 圆方树的构造 实现 细节 圆方树的运用 「BZOJ 3331」压力 「洛谷 P4320」道路相遇 「APIO 2018」「洛谷 P4630」铁人两项 「CF 487E」Touris ...
- 仙人掌&圆方树
仙人掌&圆方树 Tags:图论 [x] [luogu4320]道路相遇 https://www.luogu.org/problemnew/show/P4320 [ ] [SDOI2018]战略 ...
- 圆方树简介(UOJ30:CF Round #278 Tourists)
我写这篇博客的原因 证明我也是学过圆方树的 顺便存存代码 前置技能 双联通分量:点双 然后就没辣 圆方树 建立 新建一个图 定义原图中的所有点为圆点 对于每个点双联通分量(只有两个点的也算) 建立一个 ...
随机推荐
- Cron 表达式学习
1.7个子域的说明 cron 的表达式是字符串,实际上是由七子表达式(从左到右),描述个别细节的时间表.这些子表达式是分开的空白. 顺序(从左到右) 子串 有效数字 有效字符 1 Seconds(秒) ...
- go语言简单介绍,增强了解
1. Go语言没有类和继承的概念,所以它和 Java 或 C++ 看起来并不相同.但是它通过接口(interface)的概念来实现多态性.Go语言有一个清晰易懂的轻量级类型系统,在类型之间也没有层级之 ...
- matplotlib画图总结--多子图布局
1.subplot布局 subplot(nrows, ncols, index, **kwargs) subplot(pos, **kwargs) subplot(ax) x=[1,2,3] valu ...
- BIO和NIO实现文件复制
普通文件复制 public void copyFile() throws Exception{ FileInputStream fis=new FileInputStream("C:\\Us ...
- 数组工具类 Arrays
public static String toString(数组),将参数数组变成字符串,用来实现数组常见的操作 public static void sort(数组),按照批人升序对数组的元素进行 ...
- jdk1.8 Maven 的安装教程
1.下载java1.8 URL: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-213315 ...
- Kubernetes---资源控制器之ReplicationController、ReplicaSet和Deployment
1.ReplicationController和ReplicaSet介绍 RC(ReplicationController)主要的作用就是用来确保容器应用的副本数始终保持在用户定义的副本数.即如果有容 ...
- 【leetcode】153. 寻找旋转排序数组中的最小值
题目链接:传送门 题目描述 现有一个有序数组,假设从某个数开始将它后面的数按顺序放到了数组前面.(即 [0,1,2,4,5,6,7] 可能变成 [4,5,6,7,0,1,2]). 请找出数组中的最小元 ...
- Skywalking的增强与拦截机制
整理自架构经理(汤哥)的分享 字节增强条件匹配 在 skywalking 中实现很多基于 byte-buddy 的关于链式匹配查询的实现, 代码如下所示: public abstract class ...
- Api文档生成工具与Api文档的传播(pdf)
点击查看apidoc生成文档demo 1 环境和工具 win10 apidoc:注释生成api文档 wkhtmltopdf:apidoc生成的是html,不适合传播,于是通过wkhtmltopdf将h ...