【BZOJ3331】[BeiJing2013]压力

Description

如今,路由器和交换机构建起了互联网的骨架。处在互联网的骨干位置的核心路由器典型的要处理100Gbit/s的网络流量。他们每天都生活在巨大的压力之下。
小强建立了一个模型。这世界上有N个网络设备,他们之间有M个双向的链接。这个世界是连通的。在一段时间里,有Q个数据包要从一个网络设备发送到另一个网络设备。
一个网络设备承受的压力有多大呢?很显然,这取决于Q个数据包各自走的路径。不过,某些数据包无论走什么路径都不可避免的要通过某些网络设备。
你要计算:对每个网络设备,必须通过(包括起点、终点)他的数据包有多少个?

Input

第一行包含3个由空格隔开的正整数N,M,Q。
接下来M行,每行两个整数u,v,表示第u个网络设备(从1开始编号)和第v个网络设备之间有一个链接。u不会等于v。两个网络设备之间可能有多个链接。
接下来Q行,每行两个整数p,q,表示第p个网络设备向第q个网络设备发送了一个数据包。p不会等于q。

Output

输出N行,每行1个整数,表示必须通过某个网络设备的数据包的数量。

Sample Input

4 4 2
1 2
1 3
2 3
1 4
4 2
4 3

Sample Output

2
1
1
2

HINT

【样例解释】
设备1、2、3之间两两有链接,4只和1有链接。4想向2和3各发送一个数据包。显然,这两个数据包必须要经过它的起点、终点和1。
【数据规模和约定】
对于40%的数据,N,M,Q≤2000
对于60%的数据,N,M,Q≤40000
对于100%的数据,N≤100000,M,Q≤200000

题解:显然先用Tarjan求缩块。。。怎么求呢。。。基本功不扎实又去学了一发。

最后我们会得到一个树形结构,但是。。。怎么得到呢。。。其实对于每个块新建一个点连向块中的所有点即可。

然后就是一个类似于树的东西了,怎么统计树上有哪些路径必经一个点呢?差分即可。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=200010;
int n,m,q,top,tot,sum,cnt;
int sta[maxn],low[maxn],HEAD[maxn],NEXT[maxn<<1],TO[maxn<<1],head[maxn<<1],next[maxn<<2],to[maxn<<2];
int s[maxn<<1],fa[19][maxn<<1],Log[maxn<<1],dep[maxn<<1],Q[maxn<<1];
inline void ADD(int a,int b)
{
TO[cnt]=b,NEXT[cnt]=HEAD[a],HEAD[a]=cnt++;
}
inline void add(int a,int b)
{
to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
void tarjan(int x)
{
dep[x]=low[x]=++tot,sta[++top]=x;
for(int y,i=HEAD[x],t;i!=-1;i=NEXT[i])
{
y=TO[i];
if(!dep[y])
{
tarjan(y),low[x]=min(low[x],low[y]);
if(low[y]>=dep[x])
{
sum++;
do
{
t=sta[top--],add(sum,t),add(t,sum);
}while(t!=y);
add(sum,x),add(x,sum);
}
}
else low[x]=min(low[x],dep[y]);
}
}
void dfs(int x)
{
Q[++Q[0]]=x;
for(int i=head[x];i!=-1;i=next[i]) if(to[i]!=fa[0][x]) fa[0][to[i]]=x,dep[to[i]]=dep[x]+1,dfs(to[i]);
}
inline int lca(int a,int b)
{
int i;
if(dep[a]<dep[b]) swap(a,b);
for(i=Log[dep[a]-dep[b]];i>=0;i--) if(dep[fa[i][a]]>=dep[b]) a=fa[i][a];
if(a==b) return a;
for(i=Log[dep[a]];i>=0;i--) if(fa[i][a]!=fa[i][b]) a=fa[i][a],b=fa[i][b];
return fa[0][a];
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
//freopen("bz3331.in","r",stdin);
n=rd(),m=rd(),q=rd(),sum=n;
memset(head,-1,sizeof(head)),memset(HEAD,-1,sizeof(HEAD));
int i,j,a,b,c;
for(i=1;i<=m;i++) a=rd(),b=rd(),ADD(a,b),ADD(b,a);
cnt=0,tarjan(1),dep[1]=1,dfs(1);
for(i=2;i<=sum;i++) Log[i]=Log[i>>1]+1;
for(j=1;(1<<j)<=sum;j++) for(i=1;i<=sum;i++) fa[j][i]=fa[j-1][fa[j-1][i]];
for(i=1;i<=q;i++)
{
a=rd(),b=rd(),c=lca(a,b);
s[a]++,s[b]++,s[c]--,s[fa[0][c]]--;
}
for(i=sum;i;i--) a=Q[i],s[fa[0][a]]+=s[a];
for(i=1;i<=n;i++) printf("%d\n",s[i]);
return 0;
}

【BZOJ3331】[BeiJing2013]压力 Tarjan求点双的更多相关文章

  1. hdu 2460(tarjan求边双连通分量+LCA)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2460 思路:题目的意思是要求在原图中加边后桥的数量,首先我们可以通过Tarjan求边双连通分量,对于边 ...

  2. C++[Tarjan求点双连通分量,割点][HNOI2012]矿场搭建

    最近在学图论相关的内容,阅读这篇博客的前提是你已经基本了解了Tarjan求点双. 由割点的定义(删去这个点就可使这个图不连通)我们可以知道,坍塌的挖煤点只有在割点上才会使这个图不连通,而除了割点的其他 ...

  3. [Codeforces 555E]Case of Computer Network(Tarjan求边-双连通分量+树上差分)

    [Codeforces 555E]Case of Computer Network(Tarjan求边-双连通分量+树上差分) 题面 给出一个无向图,以及q条有向路径.问是否存在一种给边定向的方案,使得 ...

  4. 6409. 【NOIP2019模拟11.06】困难的图论(Tarjan求点双)

    题目描述 Description 给定由 n 个点 m 条边组成的无向连通图,保证没有重边和自环. 你需要找出所有边,满足这些边恰好存在于一个简单环中.一个环被称为简单环,当且仅当它包含的所有点都只在 ...

  5. 洛谷P2860 [USACO06JAN]冗余路径Redundant Paths(tarjan求边双联通分量)

    题目描述 In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numbered 1. ...

  6. POJ 2942 Knights of the Round Table 补图+tarjan求点双联通分量+二分图染色+debug

    题面还好,就不描述了 重点说题解: 由于仇恨关系不好处理,所以可以搞补图存不仇恨关系, 如果一个桌子上面的人能坐到一起,显然他们满足能构成一个环 所以跑点双联通分量 求点双联通分量我用的是向栈中pus ...

  7. [HNOI2012]矿场搭建(tarjan求点双)

    题目 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处.于是矿主决定在某些挖煤点设立救援出口,使得无 ...

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

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

  9. BZOJ3331: [BeiJing2013]压力

    传送门 Tarjan的三大应用之一:求解点双联通分量. 求解点双联通分量.然后缩点,差分优化即可. //BZOJ 3331 //by Cydiater //2016.10.29 #include &l ...

随机推荐

  1. LAMP中php配置

    内容概要:一.  php配置1. 配置disable_functiondisable_functions = eval,assert,popen,passthru,escapeshellarg,esc ...

  2. Hive 性能调优

    避免执行MR select * or select field1,field2 limit 10 where语句中只有分区字段或该表的本地字段 使用本地set hive.exec.mode.local ...

  3. Elasticsearch 之 query与filter区别

    转载: http://xiaorui.cc/category/elasticsearch/ http://blog.csdn.net/asia_kobe/article/details/5056301 ...

  4. redhat6.4 install 163 source

    1) 到http://mirrors.163.com的 centos帮助文档 中下载CentOS6-Base-163.repo文件,存放到/etc/yum.repo.d中 wget http://mi ...

  5. Angular 学习笔记——filter

    <!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <met ...

  6. SQL语句练习手册--第三篇

    一.CASE的两种用法 1.1 等值判断->相当于switch case (1)具体用法模板: CASE expression WHEN value1 THEN returnvalue1 WHE ...

  7. python——操作符重载(重要)

    类可以重载python的操作符   旧认识:__X__的名字 是系统定义的名字:是python特殊方法专用标识.   操作符重载使我们的对象与内置的一样.__X__的名字的方法是特殊的挂钩(hook) ...

  8. hdu4930 Fighting the Landlords(模拟 多校6)

    题目链接:pid=4930">http://acm.hdu.edu.cn/showproblem.php? pid=4930 Fighting the Landlords Time L ...

  9. 腾讯云DevOps 解决方案

    地址:https://www.qcloud.com/solution/devops 主要经历的几个阶段: 代码托管 持续集成与交互 测试管理 运维监控 项目管理 在上面图中都有,可以回过去查看.

  10. Linux中的一个命令行计算器bc简介

    假如你在一个图形桌面环境中需要一个计算器时,你可能只需要一路进行点击便可以找到一个计算器.例如,Fedora 工作站中就已经包含了一个名为 Calculator 的工具.它有着几种不同的操作模式,例如 ...