题意

如今,路由器和交换机构建起了互联网的骨架。处在互联网的骨干位置的核心路由器典型的要处理100Gbit/s的网络流量。

他们每天都生活在巨大的压力之下。小强建立了一个模型。这世界上有N个网络设备,他们之间有M个双向的链接。这个世界是连通的。

在一段时间里,有Q个数据包要从一个网络设备发送到另一个网络设备。
一个网络设备承受的压力有多大呢?很显然,这取决于Q个数据包各自走的路径。

不过,某些数据包无论走什么路径都不可避免的要通过某些网络设备。
你要计算:对每个网络设备,必须通过(包括起点、终点)他的数据包有多少个?

对于40%的数据,N,M,Q≤2000
对于60%的数据,N,M,Q≤40000
对于100%的数据,N≤100000,M,Q≤200000

分析

  这道题很有意思,如果它要是问可能通过的点有多少个,那问题就麻烦多了,所以它问必须经过的点,对于一个点来说,如果它不是割点,那么它一定不是必经的,除非它是端点,所以我们想到了什么?对点双联通分量,但是如果全缩了还是有问题,必须经过的点怎么办?如果变换一下这个图,让它两个点之间有唯一的路径,是不是就很好办了,对于唯一路径,我们很容易想到树,而又不能全缩了成为树,那就势必要用到别的树。

  所以引入一个新的树——圆方树

  这个树其实很好理解,就是原图的每个点都是圆点,方点是什么呢?一个方点对应一个点双联通分量,每个点双上的点连到这个这个方点上,这样就形成了一棵树,然后怎么办呢?如果对于每次修改都dfs一遍,显然效率是不高的,而每次发送一回数据包,就是将这一个经过的路径区间val+1,涉及区间加减,不就是差分数组嘛,所以直接u++,v++,lca--,falca--(点差分是falca--因为lca的值也要更新,边差分是lca-=2因为lca上边连着父亲节点的边是不改变的),最后直接dfs跑一遍统计答案就ok。

  这里特别强调一个坑,点双连树的时候不要直接pop到割点,而是要pop到E.to,看起来是差不多的,但是在割点到E.to之间,还可能会有点,这里说的有点不是图上边,而是栈里边有没pop的值,点没有pop的原因是没有判断到割点,而那些点是显然不是这个点双里边的,连进来就是,WA,所以这里要特别注意一下。

  

 #include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=4e5+;
struct Edge{
int to,next;
}e[N],E[N];
int Head[N],len;
void Ins(int a,int b){
e[++len].to=b;e[len].next=Head[a];Head[a]=len;
}
int H[N],l;
void I(int a,int b){
E[++l].to=b;E[l].next=H[a];H[a]=l;
}
int low[N],dfn[N],stk[N],num,top,fang;
void tarjan(int u){
dfn[u]=low[u]=++num;
stk[++top]=u;
for(int x=Head[u];x;x=e[x].next){
int v=e[x].to;
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]){
fang++;int temp;
do{
temp=stk[top--];
I(temp,fang);I(fang,temp);
}while(temp!=v);//是这里不能pop到u
I(fang,u);I(u,fang);
}
}else low[u]=min(low[u],dfn[v]);
}
}
int p[N][],dep[N];
//跑lca
void dfs(int x){
for(int i=;p[x][i];i++)
p[x][i+]=p[p[x][i]][i];
for(int i=H[x];i;i=E[i].next){
int v=E[i].to;
if(v!=p[x][]){
p[v][]=x;
dep[v]=dep[x]+;
dfs(v);
}
}
}
int Lca(int u,int v){
if(dep[u]<dep[v])swap(u,v);
int d=dep[u]-dep[v];
for(int i=;d;i++,d>>=)
if(d&)u=p[u][i];
if(u==v)return u;
for(int i=;i>=;i--)//这里又写错了刚开始,i>=0不是i,i->i>0少了个0
if(p[u][i]!=p[v][i])
u=p[u][i],v=p[v][i];
return p[u][];
}
//lca结束
int val[N];
int calc(int u){
for(int i=H[u];i;i=E[i].next){
int v=E[i].to;
if(v!=p[u][])
val[u]+=calc(v);
}
return val[u];
}
int main(){
// freopen("a.txt","r",stdin);
int m,n,q;
scanf("%d%d%d",&n,&m,&q);
fang=n;
for(int i=;i<=m;i++){
int a,b;
scanf("%d%d",&a,&b);
Ins(a,b);Ins(b,a);
}
tarjan();//图是联通的tarjan一遍就好
dfs();
while(q--){
int a,b;
scanf("%d%d",&a,&b);
int lca=Lca(a,b);
val[a]++;val[b]++;
val[lca]--;val[p[lca][]]--;//树上差分
}
calc();
for(int i=;i<=n;i++)
printf("%d\n",val[i]);
}

BZOJ 压力 tarjan 点双联通分量+树上差分+圆方树的更多相关文章

  1. POJ2942 Knights of the Round Table【Tarjan点双联通分量】【二分图染色】【补图】

    LINK 题目大意 有一群人,其中有一些人之间有矛盾,现在要求选出一些人形成一个环,这个环要满足如下条件: 1.人数大于1 2.总人数是奇数 3.有矛盾的人不能相邻 问有多少人不能和任何人形成任何的环 ...

  2. [J]computer network tarjan边双联通分量+树的直径

    https://odzkskevi.qnssl.com/b660f16d70db1969261cd8b11235ec99?v=1537580031 [2012-2013 ACM Central Reg ...

  3. POJ 3694Network(Tarjan边双联通分量 + 缩点 + LCA并查集维护)

    [题意]: 有N个结点M条边的图,有Q次操作,每次操作在点x, y之间加一条边,加完E(x, y)后还有几个桥(割边),每次操作会累积,影响下一次操作. [思路]: 先用Tarjan求出一开始总的桥的 ...

  4. BZOJ 2959: 长跑 lct 双联通分量 并查集 splay

    http://www.lydsy.com/JudgeOnline/problem.php?id=2959 用两个并查集维护双联通分量的编号和合并. #include<iostream> # ...

  5. POJ3177 Redundant Paths【tarjan边双联通分量】

    LINK 题目大意 给你一个有重边的无向图图,问你最少连接多少条边可以使得整个图双联通 思路 就是个边双的模板 注意判重边的时候只对父亲节点需要考虑 你就dfs的时候记录一下出现了多少条连向父亲的边就 ...

  6. tarjan求双联通分量(割点,割边)

    之前一直对tarjan算法的这几种不同应用比较混淆...我太弱啦! 被BLO暴虐滚过来 用tarjan求点双,很多神犇都给出了比较详细的解释和证明,在这里就不讲了(其实是这只蒟蒻根本不会orz) 这里 ...

  7. [hdu2460]network(依次连边并询问图中割边数量) tarjan边双联通分量+lca

    题意: 给定一个n个点m条边的无向图,q个操作,每个操作给(x,y)连边并询问此时图中的割边有多少条.(连上的边会一直存在) n<=1e5,m<=2*10^5,q<=1e3,多组数据 ...

  8. 【洛谷 SP2878】Knights of the Round Table(双联通分量)

    先放这吧,没时间写,明天再补 "明天到了" 题目链接 题意:求不在任何奇环内的点的数量. Tarjan求点双联通分量,然后再染色判断是不是二分图就好了. 只是不懂为什么Tarjan ...

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

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

随机推荐

  1. Linux 环境 搭建Git 服务器,并且修改SSH端口使用

    1.环境配置说明 服务器 CentOS 7 + git(git version 1.8.3.1) 客户端 Windows10 + SourceTree 2.安装 Git 服务器端安装: sudo yu ...

  2. 达拉草201771010105《面向对象程序设计(java)》第九周学习总结

    达拉草201771010105<面向对象程序设计(java)>第九周学习总结 实验九异常.断言与日志 实验时间 2018-10-25 1.实验目的与要求 (1) 掌握java异常处理技术: ...

  3. 【Java】Map总结和源码注释

    前言 Map为一个Java中一个重要的数据结构,主要表示<key, value>的映射关系对.本文包括了相关Map数据结构的总结和源码的阅读注释. HashMap 初始化,可以选择第二个初 ...

  4. python中if __name__ == '__main__'是什么?

    __name__和__main__认识 作用:一般用于测试程序的功能,if __name__ == '__main__':下面的代码会被执行,但当前.py文件被当做模块导入的时候,main下面的代码就 ...

  5. centos安装图形界面通常有两种方式

    centos安装图形界面通常有两种方式   1.通过系统安装,在配置选择软件界面,选择GNOME桌面模式.

  6. PyCharm使用技巧及常用快捷键

    Ctrl + Shift + F--------------------------------------------->>>>>>>高级查找 Ctrl + ...

  7. 使用HBuilder开发移动APP:ajax调用接口数据

    既然要做APP,与接口交互式少不了的,除非只是想做一个纯静态的APP.所以html5+的环境准备好后,我最先开始研究的就是如何与接口交互. 使用HBuilder新建示例教程后,里面会有一个ajax(网 ...

  8. ant tree 展开key的集合

    这次有个功能 ant的tree 展开 点击子节点 新增节点之后 数据能够照常展开 有几种方法 我能想到的 因为ant 有个expanded 只要设置为true就能展开了,但是这边有个陷阱,就是仅仅设置 ...

  9. WEB渗透 - SQL注入(持续更新)

    SQL注入 按变量类型分:数字型和字符型 按HTTP提交方式分:POST注入.GET注入和Cookie注入 按注入方式分:布尔注入.联合注入.多语句注入.报错注入.延时注入.内联注入 按数据库类型分: ...

  10. openwrt 为软件包添加服务

    手动修改 rc.local 加入也可以实现自启动,缺点手动修改太麻烦,停止只能用 kill . 配置成服务最方便了,可以启用或禁用,启动,停止,重启非常方便. 在openwrt 中使用服务 servi ...