题目链接

圆方树

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

性质

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. 安装sqlprompt

    特别说明:注册机会报毒,安装前请先关闭杀毒软件!下载好附件之后解压,打开SQLPrompt_7.2.0.241.exe按照提示安装完成.安装完成后断网!打开数据库,会在菜单栏中看到SQL Prompt ...

  2. vue中组件绑定事件时是否加.native

    组件绑定事件时 1. 普通组件绑定事件不能添加.native, 添加后事件失效 2. 自定义组件绑定事件需要添加.native, 否则事件无效 <template> <!-- < ...

  3. Python学习之路——Day02

    今日内容: 1.编程语言介绍(***) 2.python介绍(***) 3.安装cpython解释器(多个版本)(****) 4.运行python程序的两种方式(****) 4.1 交互式 4.2 命 ...

  4. pixel和nexus设备安卓9.0/8.1/7.1.x/6.x WiFi和信号图标出现叉x号或者感叹号的消除办 法

    在安卓9.0/8.1/8.0/7.1.2里如何消除x号(在老一点点版本是感叹号)呢? 1.首先开启usb调试,然后用数据线连接电脑和手机. 2.然后解决好您的adb驱动问题,具体教程见:http:// ...

  5. Installing Office Online Server for SharePoint 2016

    Office Online Server is the next version of the Office Web Apps, which allows your users to view and ...

  6. PC平台主要SIMD扩展发展简史

    Single Instruction Multiple Data,简称SIMD.SIMD描述的是微处理器中单条指令能完成对数据的并行处理.SIMD所使用的是特殊的寄存器,一个寄存器上存储有多个数据,在 ...

  7. BZOJ5063旅游——非旋转treap

    题目描述 小奇成功打开了大科学家的电脑. 大科学家打算前往n处景点旅游,他用一个序列来维护它们之间的顺序.初 始时,序列为1,2,...,n. 接着,大科学家进行m次操作来打乱顺序.每次操作有6步: ...

  8. Cetos 中添加bbr服务

    说明:此方法只适用于KVM架构的,OpenVZ平台无法使用: 一:安装bbr服务: # wget --no-check-certificate https://github.com/teddysun/ ...

  9. Tournament ZOJ - 4063 (青岛区域赛 F 打表)

    打表题.. 规律是找出来了 奈何优化不了 .... #include <iostream> #include <cstdio> #include <sstream> ...

  10. 「BZOJ1691」[Usaco2007 Dec] 挑剔的美食家 (Treap)

    Description 与很多奶牛一样,Farmer John那群养尊处优的奶牛们对食物越来越挑剔,随便拿堆草就能打发她们午饭的日子自然是一去不返了.现在,Farmer John不得不去牧草专供商那里 ...