题目链接

圆方树

圆方树就是对于联通无向图中的每一个点双新建一个方点,与点双中的每个点连一条边,然后将原来的边删去。将原来的点看作圆点,新建的点看作方点。所以叫做圆方树。

性质

1.圆方树肯定是棵树(废话)。证明显然。

2.圆方树中与圆点相连的点肯定是方点。与方点相连的点肯定是圆点。

算法

根据圆方树的定义就可以知道。构建圆方树的过程实际上就是找点双的过程。本质上就是找割点。所以用tarjan来做就好了。将找出的点双中的点与新建的点连边即可。

思路

这个题就是圆方树的经典应用,先对于原图构建出圆方树。那么对于每个从S到T的路径。在圆方树上两点之间的简单路径上的圆点就是在原图中必须经过的点。然后再圆方树上差分一下就行了。

代码

/*
* @Author: wxyww
* @Date: 2019-01-22 20:03:52
* @Last Modified time: 2019-01-22 20:42:20
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<bitset>
#include<vector>
using namespace std;
typedef long long ll;
const int N = 200000 + 100,logN = 20;
vector<int>E[N * 2];
ll read() {
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
struct node {
int u,v,nxt;
}e[N * 4];
int head[N],ejs;
void add(int u,int v) {
e[++ejs].u = u;e[ejs].v = v;e[ejs].nxt = head[u];head[u] = ejs;
}
void ADD(int u,int v) {
// printf("!!!%d %d\n",u,v);
E[u].push_back(v);E[v].push_back(u);
}
int top,sta[N];
int coljs,n,m,Q,cnt,dfn[N],low[N];
void tarjan(int u) {
dfn[u] = low[u] = ++cnt;
sta[++top] = u;
for(int i = head[u];i;i = e[i].nxt) {
int v = e[i].v;
// if(v == father) continue;
if(!dfn[v]) {
tarjan(v);
low[u] = min(low[u],low[v]);
if(low[v] >= dfn[u]) {
++n;
ADD(n,u);
while(sta[top + 1] != v) {
ADD(n,sta[top--]);
}
}
}
else low[u] = min(low[u],dfn[v]);
}
}
int dep[N];
int lca[N][logN];
void dfs(int u,int father) {
dep[u] = dep[father] + 1;
for(int i = 1;i < logN;++i)
lca[u][i] = lca[lca[u][i - 1]][i - 1];
int k = E[u].size();
for(int i = 0;i < k;++i) {
int v = E[u][i];
if(v == father) continue;
lca[v][0] = u;
dfs(v,u);
}
}
int LCA(int x,int y) {
if(dep[x] < dep[y]) swap(x,y);
for(int i = logN - 1;i >= 0;--i) {
if(dep[lca[x][i]] >= dep[y]) x = lca[x][i];
}
for(int i = logN - 1;i >= 0;--i) {
if(lca[x][i] != lca[y][i]) {
x = lca[x][i];y = lca[y][i];
}
}
if(x != y) x = lca[x][0];
return x;
}
int sum[N];
void dfs2(int u,int father) {
int k = E[u].size();
for(int i = 0;i < k;++i) {
int v = E[u][i];
if(v == father) continue;
dfs2(v,u);
sum[u] += sum[v];
}
}
int main() {
n = read(),m = read(),Q = read();
int nn = n;
for(int i = 1;i <= m;++i) {
int u = read(),v = read();
add(u,v);add(v,u);
}
tarjan(1);
dfs(1,0);
for(int i = 1;i <= Q;++i) {
int u = read(),v = read();
int L = LCA(u,v);
// printf("%d\n",L);
sum[u]++;sum[v]++;sum[L]--;sum[lca[L][0]]--;
}
dfs2(1,0);
for(int i = 1;i <= nn;++i) printf("%d\n",sum[i]);
return 0;
}

bzoj3331 压力(圆方树)的更多相关文章

  1. BZOJ3331 [BeiJing2013]压力[圆方树+树上差分]

    圆方树新技能get.具体笔记见图连通性问题学习笔记. 这题求无向图的必经点,这个是一个固定套路:首先,一张连通的无向图中,每对点双和点双之间是以一个且仅一个割点连接起来的(如果超过一个就不能是割点了) ...

  2. BZOJ3331 压力 (圆方树+树上差分)

    题意 略 题解 求路径上的割点. 然后就直接圆方树上差分 CODE #include <bits/stdc++.h> using namespace std; inline void rd ...

  3. BZOJ 压力 tarjan 点双联通分量+树上差分+圆方树

    题意 如今,路由器和交换机构建起了互联网的骨架.处在互联网的骨干位置的核心路由器典型的要处理100Gbit/s的网络流量. 他们每天都生活在巨大的压力之下.小强建立了一个模型.这世界上有N个网络设备, ...

  4. 仙人掌&圆方树

    仙人掌&圆方树 Tags:图论 [x] [luogu4320]道路相遇 https://www.luogu.org/problemnew/show/P4320 [ ] [SDOI2018]战略 ...

  5. 仙人掌 && 圆方树 && 虚树 总结

    仙人掌 && 圆方树 && 虚树 总结 Part1 仙人掌 定义 仙人掌是满足以下两个限制的图: 图完全联通. 不存在一条边处在两个环中. 其中第二个限制让仙人掌的题做 ...

  6. Traffic Real Time Query System 圆方树+LCA

    题目描述 City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, ...

  7. Note -「圆方树」学习笔记

    目录 圆方树的定义 圆方树的构造 实现 细节 圆方树的运用 「BZOJ 3331」压力 「洛谷 P4320」道路相遇 「APIO 2018」「洛谷 P4630」铁人两项 「CF 487E」Touris ...

  8. 圆方树简介(UOJ30:CF Round #278 Tourists)

    我写这篇博客的原因 证明我也是学过圆方树的 顺便存存代码 前置技能 双联通分量:点双 然后就没辣 圆方树 建立 新建一个图 定义原图中的所有点为圆点 对于每个点双联通分量(只有两个点的也算) 建立一个 ...

  9. 洛谷P4630 铁人两项--圆方树

    一道很好的圆方树入门题 感谢PinkRabbit巨佬的博客,讲的太好啦 首先是构建圆方树的代码,也比较好想好记 void tarjan(int u) { dfn[u] = low[u] = ++dfn ...

随机推荐

  1. vue-axios的application/x-www-form-urlencod的post请求无法解析参数

    vue-axios的post会先将对象转为json然后再根据headers的设置再转一次格式,可以将参数先用qs.stringify()转一次再传输

  2. mysql常用运算符

    一.算数运算符 + 加法 - 减法 * 乘法 / 除法 % 返回余数 二.比较运算符 = 等于 <>或!= 不等于 <=> 等于(这里是安全的等于 例如: select nul ...

  3. 使用synchronized 实现ReentrantLock(美团面试题目)

    刚看到这个题目的时候无从下手,因为觉得synchronized和lock在加锁的方式上有很大不同,比如,看看正常情况下synchronized时如何加锁的. 方式一: public synchroni ...

  4. 日志与python日志组件logging

    1. 日志的相关概念: (1)日志的作用: a. 开发人员进行程序调试 b. 开发人员定位程序故障的位置 c. 运维人员观察应用运行是否正常 (2)日志的等级 a. DEBUG 最详细的日志,用于问题 ...

  5. JavaScript控制阻止表单提交

    1.在表单上使用onSubmit方法 <?php $form = ActiveForm::begin([ 'options'=>[ 'class' => 'form-horizont ...

  6. vue動畫和過渡

    過渡: 插入.更新和溢出DOM時,提供不同的方式應用過渡效果: vue提供內置的封裝組件,用於包裹要實現過渡效果的內容. <transition name="a">&l ...

  7. 一、.NET Core MVC 项目结构模板

    一.图文描述,开口干 二.文件结构:  wwwroot 首先,Razor Pages项目中多了一个wwwroot的文件夹,这个文件夹中,主要存放网站的静态资源,如css,网站图片资源文件,js文件,三 ...

  8. mybatis-spring-1.2.2.jar下载地址

    http://www.java2s.com/Code/Jar/m/Downloadmybatisspring120jar.htm

  9. Nginx 负载均衡一致性算法

    一般Hash负载算法都是%算法 比如key-5 如果有5台服务器 那么5%5=0  那么请求将落在server 0 上,当有服务器宕机或者添加新服务器时,hash算法会引发大量路由更改,可能导致缓存大 ...

  10. 洛谷 P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm

    题目描述 每年,在威斯康星州,奶牛们都会穿上衣服,收集农夫约翰在N(1<=N<=100,000)个牛棚隔间中留下的糖果,以此来庆祝美国秋天的万圣节. 由于牛棚不太大,FJ通过指定奶牛必须遵 ...